57template<
typename SampleType>
84 DSPFunction (std::function<SampleType (SampleType)> dspFunction,
const std::string& label = {}):
85 m_dspFunctionSampleWise (std::move (dspFunction)), m_label (label)
123 m_dspFunctionBlockWiseReplacing (std::move (dspFunction)), m_label (label)
157 m_dspFunctionBlockWiseNonReplacing (std::move (dspFunction)), m_label (label)
161 void prepare (
double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames)
override
165 m_dspFunctionBlockWiseNonReplacing !=
nullptr
166 || m_dspFunctionBlockWiseReplacing !=
nullptr
167 || m_dspFunctionSampleWise !=
nullptr);
169 if (m_dspFunctionBlockWiseReplacing !=
nullptr)
171 const size_t maxChannels = std::max (numInputChannels, numOutputChannels);
172 m_inputOutputBuffer =
AudioBuffer<SampleType> (maxChannels, maxBlockSizeFrames, sampleRateHz);
178 if (m_dspFunctionBlockWiseNonReplacing !=
nullptr)
180 processBlockWiseNonReplacing (input, output);
184 if (m_dspFunctionBlockWiseReplacing !=
nullptr)
186 processBlockWiseReplacing (input, output);
190 if (m_dspFunctionSampleWise !=
nullptr)
192 processSampleWise (input, output);
201 stream <<
"DSPFunction (<function>, \"" << m_label <<
"\")";
213 if (m_dspFunctionSampleWise !=
nullptr)
214 return numInputChannels == numOutputChannels;
223 hassert (input.getNumChannels() == output.getNumChannels());
225 const size_t numChannels = input.getNumChannels();
226 const size_t numFrames = input.getNumFrames();
228 for (size_t channel = 0; channel < numChannels; ++channel)
229 for (size_t i = 0; i < numFrames; ++i)
230 output[channel][i] = m_dspFunctionSampleWise (input[channel][i]);
235 const size_t numFrames = input.getNumFrames();
237 if (m_inputOutputBuffer.getNumFrames() != numFrames)
238 m_inputOutputBuffer.setNumFrames (numFrames);
240 for (size_t channel = 0; channel < input.getNumChannels(); ++channel)
241 m_inputOutputBuffer.copyFrom (channel, 0, input, channel, 0, numFrames);
243 for (size_t channel = input.getNumChannels(); channel < m_inputOutputBuffer.getNumChannels(); ++channel)
244 m_inputOutputBuffer.clear (channel, 0, numFrames);
246 const size_t originalNumChannels = m_inputOutputBuffer.getNumChannels();
247 const size_t originalNumFrames = m_inputOutputBuffer.getNumFrames();
248 const double originalSampleRateHz = m_inputOutputBuffer.getSampleRateHz();
250 m_dspFunctionBlockWiseReplacing (m_inputOutputBuffer);
252 if (m_inputOutputBuffer.getNumChannels() != originalNumChannels)
255 if (m_inputOutputBuffer.getNumFrames() != originalNumFrames)
258 if (!floatsEqual (m_inputOutputBuffer.getSampleRateHz(), originalSampleRateHz))
261 for (size_t channel = 0; channel < output.getNumChannels(); ++channel)
262 output.copyFrom (channel, 0, m_inputOutputBuffer, channel, 0, numFrames);
267 const size_t originalNumChannels = output.getNumChannels();
268 const size_t originalNumFrames = output.getNumFrames();
269 const double originalSampleRateHz = output.getSampleRateHz();
271 m_dspFunctionBlockWiseNonReplacing (input, output);
275 if (output.getNumChannels() != originalNumChannels)
278 if (output.getNumFrames() != originalNumFrames)
281 if (! floatsEqual (output.getSampleRateHz(), originalSampleRateHz))
286 std::function<SampleType (SampleType)> m_dspFunctionSampleWise =
nullptr;
287 std::function<
void (
AudioBuffer<SampleType>&)> m_dspFunctionBlockWiseReplacing =
nullptr;
288 std::function<
void (
const AudioBuffer<SampleType>&,
AudioBuffer<SampleType>&)> m_dspFunctionBlockWiseNonReplacing =
nullptr;
Container for audio data.
A set of boolean flags mapped to each audio channel.
Thrown when a numbers of channels is mismatched.
A DSP processor defined by a user-provided function.
DSPFunction(std::function< void(AudioBuffer< SampleType > &)> dspFunction, const std::string &label={})
Creates a DSP instance based on a block-wise replacing (in-place) DSP function.
DSPFunction(std::function< void(const AudioBuffer< SampleType > &, AudioBuffer< SampleType > &)> dspFunction, const std::string &label={})
Creates a DSP instance based on a block-wise non-replacing (separate input and output buffers) DSP fu...
void setValue(int, double) override
Sets DSP value.
void process(const AudioBuffer< SampleType > &input, AudioBuffer< SampleType > &output, const EnvelopeBuffers &, ChannelFlags) override
Processes the audio.
void represent(std::ostream &stream) const override
Makes a text representation of this DSP effect for test failure outputs.
void prepare(double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames) override
Prepare for processing.
bool supportsEnvelopeFor(int) const override
Tells whether this effect accepts automation envelopes for a particular parameter.
bool supportsSampleRate(double) const override
Tells whether this effect supports given sample rate.
DSPFunction(std::function< SampleType(SampleType)> dspFunction, const std::string &label={})
Creates a DSP instance based on a sample-wise DSP function.
void reset() override
Resets to initial state.
bool supportsChannelLayout(size_t numInputChannels, size_t numOutputChannels) const override
Tells the runner (host) whether this effect supports a specific i/o configuration.
Thrown when a nullptr could be handled gracefully.
Thrown when sample rate is mismatched.
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
#define HART_DSP_DECLARE_ALIASES_FOR(ClassName)