4#include "signals/hart_signal.hpp"
16template<
typename SampleType>
29 m_buffer (std::move (buffer)),
32 if (m_buffer ==
nullptr)
35 this->setNumChannels (m_buffer->getNumChannels());
40 m_buffer (std::make_shared<
AudioBuffer<SampleType>> (buffer)),
43 this->setNumChannels (m_buffer->getNumChannels());
48 m_buffer (std::make_shared<
AudioBuffer<SampleType>> (std::move (buffer))),
51 this->setNumChannels (m_buffer->getNumChannels());
56 return m_buffer !=
nullptr && numChannels == m_buffer->getNumChannels();
61 if (m_buffer ==
nullptr)
65 return ! m_buffer->hasSampleRate() || m_buffer->getSampleRateHz() == sampleRateHz;
68 void prepare (
double sampleRateHz, size_t numOutputChannels, size_t )
override
70 if (m_buffer ==
nullptr)
73 if (numOutputChannels != m_buffer->getNumChannels())
76 if (m_buffer->hasSampleRate() && m_buffer->getSampleRateHz() != sampleRateHz)
82 if (m_buffer ==
nullptr)
89 const size_t numFrames = output.getNumFrames();
90 const size_t bufferTotalFrames = m_buffer->getNumFrames();
91 const size_t bufferNumChannels = m_buffer->getNumChannels();
92 size_t framesWritten = 0;
94 while (framesWritten < numFrames)
96 if (m_readPosition >= bufferTotalFrames)
98 if (m_loop ==
Loop::no)
104 const size_t framesAvailable = bufferTotalFrames - m_readPosition;
105 const size_t framesToCopy = std::min (framesAvailable, numFrames - framesWritten);
107 for (size_t channel = 0; channel < bufferNumChannels; ++channel)
109 const SampleType* src = (*m_buffer)[channel] + m_readPosition;
110 SampleType* dst = output[channel] + framesWritten;
111 std::copy(src, src + framesToCopy, dst);
114 framesWritten += framesToCopy;
115 m_readPosition += framesToCopy;
119 for (; framesWritten < numFrames; ++framesWritten)
120 for (size_t channel = 0; channel < bufferNumChannels; ++channel)
121 output[channel][framesWritten] = SampleType(0);
131 stream <<
"AudioBufferSignal (";
133 if (m_buffer !=
nullptr)
134 m_buffer->represent (stream);
136 stream <<
"<nullptr>";
138 stream <<
", Loop::" << (m_loop ==
Loop::yes ?
"yes" :
"no") <<
')';
141 std::unique_ptr<SignalBase<SampleType>>
copy()
const override
146 std::unique_ptr<SignalBase<SampleType>>
move()
override
154 size_t m_readPosition = 0;
Plays audio from a pre-rendered AudioBuffer.
void renderNextBlock(AudioBuffer< SampleType > &output) override
Renders next block audio for the signal.
bool supportsSampleRate(double sampleRateHz) const override
Tells whether this Signal supports given sample rate.
AudioBufferSignal(std::shared_ptr< AudioBuffer< SampleType > > buffer, Loop loop=Loop::no)
Construct from a shared_ptr (shared ownership)
AudioBufferSignal(const AudioBuffer< SampleType > &buffer, Loop loop=Loop::no)
Construct by copying a buffer (takes ownership of a copy)
void prepare(double sampleRateHz, size_t numOutputChannels, size_t) override
Prepare the signal for rendering.
void represent(std::ostream &stream) const override
Makes a text representation of this Signal for test failure outputs.
std::unique_ptr< SignalBase< SampleType > > move() override
Returns a smart pointer with a moved instance of this object.
bool supportsNumChannels(size_t numChannels) const override
Tells the host whether this Signal is capable of generating audio for a certain amount of channels.
std::unique_ptr< SignalBase< SampleType > > copy() const override
Returns a smart pointer with a copy of this object.
AudioBufferSignal(AudioBuffer< SampleType > &&buffer, Loop loop=Loop::no)
Construct by moving a buffer (takes ownership)
void reset() override
Resets the Signal to initial state.
Container for audio data.
Thrown when a numbers of channels is mismatched.
Thrown when a nullptr could be handled gracefully.
Thrown when sample rate is mismatched.
#define HART_THROW_OR_RETURN_VOID(ExceptionType, message)
Throws an exception if HART_DO_NOT_THROW_EXCEPTIONS is set, prints a message and returns otherwise.
#define hassertfalse
Triggers a HartAssertException
#define HART_SIGNAL_DECLARE_ALIASES_FOR(ClassName)