7#include <unordered_map>
10#include "envelopes/hart_envelope.hpp"
22using EnvelopeBuffers = std::unordered_map<
int, std::vector<
double>>;
32template <
typename SampleType>
47 virtual void prepare (
double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames) = 0;
81 virtual void setValue (
int paramId,
double value) = 0;
89 virtual double getValue (
int paramId)
const = 0;
105 virtual void represent (std::ostream& stream)
const = 0;
125 virtual std::unique_ptr<
DSP<SampleType>>
copy()
const = 0;
129 virtual std::unique_ptr<
DSP<SampleType>>
move() = 0;
141 for (
auto& pair : other.m_envelopes)
142 m_envelopes.emplace (pair.first, pair.second->copy());
148 : m_envelopes (std::move (other.m_envelopes))
159 for (
auto& pair : other.m_envelopes)
160 m_envelopes.emplace (pair.first, pair.second->copy());
170 m_envelopes = std::move (other.m_envelopes);
205 m_envelopes.emplace (paramId, envelope
.copy());
216 return m_envelopes.find (paramId) != m_envelopes.end();
225 void prepareWithEnvelopes (
double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames)
227 m_envelopeBuffers.clear();
229 for (
auto& item : m_envelopes)
231 const int paramId = item.first;
232 m_envelopeBuffers.emplace (paramId, std::vector<
double> (maxBlockSizeFrames));
235 hassert (m_envelopes.size() == m_envelopeBuffers.size());
237 for (
auto& item : m_envelopeBuffers)
239 const int paramId = item.first;
240 auto& envelopeBuffer = item.second;
244 hassert (
hasEnvelopeFor (paramId
) &&
"Envelope for this param id is not attached, yet there's an envelope buffer allocated for it");
246 if (envelopeBuffer.size() != maxBlockSizeFrames)
247 envelopeBuffer.resize (maxBlockSizeFrames);
250 prepare (sampleRateHz
, numInputChannels
, numOutputChannels
, maxBlockSizeFrames
);
262 for (
auto& item : m_envelopeBuffers)
264 const int paramId = item.first;
265 auto& envelopeBuffer = item.second;
269 hassert (
hasEnvelopeFor (paramId
) &&
"Envelope for this param id is not attached, yet there's an envelope buffer allocated for it");
270 hassert (input.getNumFrames() <= envelopeBuffer.size() &&
"Envelope Buffers were not allocated properly for this buffer size");
273 getValues (paramId, envelopeBuffer.size(), envelopeBuffer);
281 using SampleTypePublicAlias = SampleType;
284 std::unordered_map<
int, std::unique_ptr<
Envelope>> m_envelopes;
285 EnvelopeBuffers m_envelopeBuffers;
291 void getValues (
int paramId, size_t blockSize, std::vector<
double>& valuesOutput)
293 if (valuesOutput.size() < blockSize)
295 HART_WARNING (
"Make sure to configure your envelope container size before processing audio");
296 valuesOutput.resize (blockSize);
302 std::fill (valuesOutput.begin(), valuesOutput.end(), value);
314template <
typename SampleType>
315inline std::ostream& operator<< (std::ostream& stream,
const DSP<SampleType>& dsp)
318 dsp.represent (stream);
334#define HART_DSP_DEFINE_COPY_AND_MOVE(ClassName)
335 std::unique_ptr<DSP<SampleType>> copy() const override {
336 return hart::make_unique<ClassName> (*this);
338 std::unique_ptr<DSP<SampleType>> move() override {
339 return hart::make_unique<ClassName> (std::move (*this));
357#define HART_DSP_FORBID_COPY_AND_MOVE
358 std::unique_ptr<DSP<SampleType>> copy() const override {
359 static_assert(false, "This DSP cannot be copied");
362 std::unique_ptr<DSP<SampleType>> move() override {
363 static_assert(false, "This DSP cannot be moved");
370#define HART_DSP_DECLARE_ALIASES_FOR(ClassName)
371 namespace aliases_float{
372 using ClassName = hart::ClassName<float>;
374 namespace aliases_double{
375 using ClassName = hart::ClassName<double>;
virtual bool supportsChannelLayout(size_t numInputChannels, size_t numOutputChannels) const =0
Tells the runner (host) whether this effect supports a specific i/o configuration.
void prepareWithEnvelopes(double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames)
Prepares all the attached envelopes and the effect itself for processing.
virtual void reset()=0
Resets to initial state.
virtual void process(const AudioBuffer< SampleType > &input, AudioBuffer< SampleType > &output, const EnvelopeBuffers &envelopeBuffers)=0
Processes the audio.
virtual void represent(std::ostream &stream) const =0
Makes a text representation of this DSP effect for test failure outputs.
virtual double getValue(int paramId) const =0
Retreives DSP value.
DSP & withEnvelope(int paramId, const Envelope &envelope)
Adds envelope to a specific parameter by copying it.
DSP & withEnvelope(int paramId, Envelope &&envelope)
Adds envelope to a specific parameter by moving it.
DSP()=default
Default constructor.
virtual ~DSP()=default
Destructor.
DSP(const DSP &other)
Copies from another DSP effect instance.
DSP & operator=(const DSP &other)
Copies from another DSP effect instance.
virtual bool supportsSampleRate(double) const
Tells whether this effect supports given sample rate.
virtual std::unique_ptr< DSP< SampleType > > move()=0
Returns a smart pointer with a moved instance of this object.
void processWithEnvelopes(const AudioBuffer< SampleType > &input, AudioBuffer< SampleType > &output)
Renders all the automation envelopes and processes the audio.
DSP & operator=(DSP &&other) noexcept
Move assignment.
virtual void prepare(double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames)=0
Prepare for processing.
virtual void setValue(int paramId, double value)=0
Sets DSP value.
bool hasEnvelopeFor(int paramId)
Checks if there's an automation envelope attached to a specific parameter.
virtual std::unique_ptr< DSP< SampleType > > copy() const =0
Returns a smart pointer with a copy of this object.
DSP(DSP &&other) noexcept
Move constructor.
virtual bool supportsEnvelopeFor(int) const
Tells whether this effect accepts automation envelopes for a particular parameter.
Represents an Envelope curve for DSP parameters.
virtual void renderNextBlock(size_t blockSize, std::vector< double > &valuesOutput)=0
virtual std::unique_ptr< Envelope > copy() const =0
std::unique_ptr< ObjectType > make_unique(Args &&... args)
std::make_unique() replacement for C++11
#define HART_WARNING(message)
#define hassert(condition)
#define HART_THROW_OR_RETURN(ExceptionType, message, returnValue)