59template<
typename SampleType>
86 DSPFunction (std::function<SampleType (SampleType)> dspFunction,
const std::string& label = {}):
87 m_dspFunctionSampleWise (std::move (dspFunction)), m_label (label)
125 m_dspFunctionBlockWiseReplacing (std::move (dspFunction)), m_label (label)
159 m_dspFunctionBlockWiseNonReplacing (std::move (dspFunction)), m_label (label)
163 void prepare (
double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames)
override
165 if (m_dspFunctionBlockWiseReplacing)
167 const size_t maxChannels = std::max (numInputChannels, numOutputChannels);
168 m_inputOutputBuffer =
AudioBuffer<SampleType> (maxChannels, maxBlockSizeFrames, sampleRateHz);
174 if (m_dspFunctionBlockWiseNonReplacing !=
nullptr)
176 processBlockWiseNonReplacing (input, output);
180 if (m_dspFunctionBlockWiseReplacing !=
nullptr)
182 processBlockWiseReplacing (input, output);
186 if (m_dspFunctionSampleWise !=
nullptr)
188 processSampleWise (input, output);
197 stream <<
"DSPFunction (<function>, \"" << m_label <<
"\")";
211 if (m_dspFunctionSampleWise !=
nullptr)
212 return numInputChannels == numOutputChannels;
221 hassert (input.getNumChannels() == output.getNumChannels());
223 const size_t numChannels = input.getNumChannels();
224 const size_t numFrames = input.getNumFrames();
226 for (size_t channel = 0; channel < numChannels; ++channel)
227 for (size_t i = 0; i < numFrames; ++i)
228 output[channel][i] = m_dspFunctionSampleWise (input[channel][i]);
233 const size_t numFrames = input.getNumFrames();
235 if (m_inputOutputBuffer.getNumFrames() != numFrames)
236 m_inputOutputBuffer.setNumFrames (numFrames);
238 for (size_t channel = 0; channel < input.getNumChannels(); ++channel)
239 m_inputOutputBuffer.copyFrom (channel, 0, input, channel, 0, numFrames);
241 for (size_t channel = input.getNumChannels(); channel < m_inputOutputBuffer.getNumChannels(); ++channel)
242 m_inputOutputBuffer.clear (channel, 0, numFrames);
244 const size_t originalNumChannels = m_inputOutputBuffer.getNumChannels();
245 const size_t originalNumFrames = m_inputOutputBuffer.getNumFrames();
246 const double originalSampleRateHz = m_inputOutputBuffer.getSampleRateHz();
248 m_dspFunctionBlockWiseReplacing (m_inputOutputBuffer);
250 if (m_inputOutputBuffer.getNumChannels() != originalNumChannels)
253 if (m_inputOutputBuffer.getNumFrames() != originalNumFrames)
256 if (!floatsEqual (m_inputOutputBuffer.getSampleRateHz(), originalSampleRateHz))
259 for (size_t channel = 0; channel < output.getNumChannels(); ++channel)
260 output.copyFrom (channel, 0, m_inputOutputBuffer, channel, 0, numFrames);
265 const size_t originalNumChannels = output.getNumChannels();
266 const size_t originalNumFrames = output.getNumFrames();
267 const double originalSampleRateHz = output.getSampleRateHz();
269 m_dspFunctionBlockWiseNonReplacing (input, output);
273 if (output.getNumChannels() != originalNumChannels)
276 if (output.getNumFrames() != originalNumFrames)
279 if (! floatsEqual (output.getSampleRateHz(), originalSampleRateHz))
284 std::function<SampleType (SampleType)> m_dspFunctionSampleWise =
nullptr;
285 std::function<
void (
AudioBuffer<SampleType>&)> m_dspFunctionBlockWiseReplacing =
nullptr;
286 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)