7#include "signals/hart_signal.hpp"
58template<
typename SampleType>
90 m_signalFunction (std::move (signalFunction)),
99 hassert (m_userBuffer !=
nullptr);
106 && output.hasSampleRate()
111 const size_t numFrames = output.getNumFrames();
112 const size_t numChannels = output.getNumChannels();
114 size_t readPos = m_userBufferOffsetFrames;
115 size_t outputOffsetFrames = 0;
117 while (outputOffsetFrames < numFrames)
119 const size_t framesAvailable = bufferFrames - readPos;
120 const size_t framesToCopy = std::min (framesAvailable, numFrames - outputOffsetFrames);
122 for (size_t channel = 0; channel < numChannels; ++channel)
125 (*m_userBuffer)
[channel
] + readPos,
126 (*m_userBuffer)
[channel
] + readPos + framesToCopy,
127 output[channel] + outputOffsetFrames
131 outputOffsetFrames += framesToCopy;
132 readPos += framesToCopy;
134 if (readPos >= bufferFrames)
143 while (outputOffsetFrames < numFrames)
145 for (size_t channel = 0; channel < numChannels; ++channel)
146 output[channel][outputOffsetFrames] =
static_cast<SampleType> (0);
148 ++outputOffsetFrames;
151 m_userBufferOffsetFrames = readPos;
154 void prepare (
double sampleRateHz, size_t numOutputChannels, size_t )
override
157 if (m_userBuffer !=
nullptr)
160 const bool bufferDoesntNeedGenerating =
161 m_userBuffer !=
nullptr
166 if (bufferDoesntNeedGenerating)
169 m_userBuffer = std::make_shared<
AudioBuffer<SampleType>> (numOutputChannels, 0, sampleRateHz);
171 if (m_signalFunction ==
nullptr)
175 m_signalFunction (*m_userBuffer);
189 m_userBufferOffsetFrames = 0;
194 stream <<
"SignalFunction (<function>, \"" << m_label << (m_loop ==
Loop::yes ?
"\", Loop::yes)" :
"\", Loop::no)");
198 const std::function <
void (
AudioBuffer<SampleType>&)> m_signalFunction =
nullptr;
199 const std::string m_label;
202 size_t m_userBufferOffsetFrames = 0;
Container for audio data.
SampleType * operator[](size_t channel)
Get a raw pointer to a specific channel's mutable audio data.
size_t getNumFrames() const
Get number of frames (samples)
bool hasSampleRate() const
Check if a specific sample rate was assigned to the audio buffer.
double getSampleRateHz() const
Get a sample rate metadata.
size_t getNumChannels() const
Get number of channels.
Thrown when a numbers of channels is mismatched.
Thrown when a nullptr could be handled gracefully.
Thrown when sample rate is mismatched.
Signal defined by a user-provided function.
void renderNextBlock(AudioBuffer< SampleType > &output) override
Renders next block audio for the signal.
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.
SignalFunction(std::function< void(AudioBuffer< SampleType > &)> signalFunction, const std::string &label={}, Loop loop=Loop::yes)
Constructs a signal from a user-defined function.
void reset() override
Resets the Signal to initial state.
Thrown when an unexpected container size is encountered.
#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 hassert(condition)
Triggers a HartAssertException if the condition is false
static SampleType floatsEqual(SampleType a, SampleType b, SampleType epsilon=(SampleType) 1e-8)
Compares two floating point numbers within a given tolerance.
Loop
Helper values for something that could loop, like a Signal.
#define HART_SIGNAL_DECLARE_ALIASES_FOR(ClassName)