48template <
typename SampleType>
60 m_dspChain (std::move (dspChain))
81 void prepare (
double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames)
override
83 for (
auto& dsp : m_dspChain)
84 dsp->prepareWithEnvelopes (sampleRateHz, numInputChannels, numOutputChannels, maxBlockSizeFrames);
89 if (m_dspChain.empty())
98 m_dspChain[0]->processWithEnvelopes (input, output);
100 if (m_dspChain.size() == 1)
104 const AudioBuffer<SampleType>& inputReplacing = output;
108 for (size_t i = 1; i < m_dspChain.size(); ++i)
109 m_dspChain[i]->processWithEnvelopes (inputReplacing, output);
114 for (
auto& dsp : m_dspChain)
115 if (! dsp->supportsSampleRate (sampleRate))
123 for (
auto& dsp : m_dspChain)
124 if (! dsp->supportsChannelLayout (numInputChannels, numOutputChannels))
135 stream <<
"HART_DSP_SEQUENCE (";
137 for (size_t i = 0; i < m_dspChain.size(); ++i)
142 m_dspChain[i]->represent (stream);
150 std::vector<std::unique_ptr<
DSPBase<SampleType>>> dspCopies;
151 dspCopies.reserve (m_dspChain.size());
153 for (size_t i = 0; i < m_dspChain.size(); ++i)
155 auto dspCopy = m_dspChain[i]->copy();
159 "DSPSequence::copy() failed because one of the contained DSP units is not copyable",
162 dspCopies.push_back (std::move (dspCopy));
172 return m_dspChain.size();
179 template<
typename DerivedDSP,
180 typename =
typename std::enable_if<
181 ! std::is_lvalue_reference<DerivedDSP>::value
184 typename std::decay<DerivedDSP>::type
189 m_dspChain.emplace_back (dsp.move());
201 m_dspChain.emplace_back (std::move (dsp));
211 return m_dspChain.at (normalizeIndex (index)).get();
221 return m_dspChain.at (normalizeIndex (index)).get();
229 std::unique_ptr<
DSPBase<SampleType>>
pop (
long long int index = -1)
231 size_t normalizedIndex = normalizeIndex (index);
232 auto iterator = m_dspChain.begin() +
static_cast<std::ptrdiff_t> (normalizedIndex);
234 std::unique_ptr<
DSPBase<SampleType>> poppedDSP = std::move (*iterator);
235 m_dspChain.erase (iterator);
240 size_t normalizeIndex (
long long int index)
const
242 const long long int size =
static_cast<
long long int> (m_dspChain.size());
243 const long long int normalizedIndex = index < 0 ? size + index : index;
245 if (normalizedIndex < 0 || normalizedIndex >= size)
248 return static_cast<size_t> (normalizedIndex);
251 std::vector<std::unique_ptr<
DSPBase<SampleType>>> m_dspChain;
261template <
typename SampleType>
262class DSPSequenceBuilder
265 DSPSequenceBuilder() =
default;
266 DSPSequenceBuilder (
const DSPSequenceBuilder&) =
delete;
267 DSPSequenceBuilder (DSPSequenceBuilder&&)
noexcept =
default;
268 DSPSequenceBuilder& operator= (
const DSPSequenceBuilder&) =
delete;
269 DSPSequenceBuilder& operator= (DSPSequenceBuilder&&)
noexcept =
default;
270 ~DSPSequenceBuilder() =
default;
272 template <
typename DerivedDSP>
273 DSPSequenceBuilder&& operator>> (DerivedDSP&& dsp) &&
275 m_dspChain.emplace_back (dsp.move());
276 return std::move (*
this);
279 DSPSequenceBuilder&& operator>> (std::unique_ptr<
DSPBase<SampleType>> dsp) &&
281 m_dspChain.emplace_back (std::move (dsp));
282 return std::move (*
this);
287 return DSPSequence<SampleType> (std::move (m_dspChain));
291 std::vector<std::unique_ptr<
DSPBase<SampleType>>> m_dspChain;
328#define HART_DSP_SEQUENCE(...)
329 (DSPSequenceBuilder() >> __VA_ARGS__).build()
346#define HART_DSP_SEQUENCE_T(SampleType, ...)
347 (hart::DSPSequenceBuilder<SampleType>() >> __VA_ARGS__).build()
Container for audio data.
A set of boolean flags mapped to each audio channel.
Polymorphic base for all DSP.
A DSP unit that renders audio through a linear sequence of DSP instances.
DSPSequence & operator=(DSPSequence &&) noexcept=default
Moves DSP chain from another DSP sequence.
bool supportsSampleRate(double sampleRate) const override
Tells whether this effect supports given sample rate.
virtual void setValue(int, double) override
Sets DSP value.
size_t size() const noexcept
Returns the number of DSP elements in the sequence.
DSPSequence(std::vector< std::unique_ptr< DSPBase< SampleType > > > dspChain)
Creates a sequence of DSP processors.
~DSPSequence() override=default
Destructor.
void process(const AudioBuffer< SampleType > &input, AudioBuffer< SampleType > &output, const EnvelopeBuffers &, ChannelFlags) override
Processes the audio.
std::unique_ptr< DSPBase< SampleType > > copy() const override
Returns a smart pointer with a copy of this object.
void represent(std::ostream &stream) const override
Makes a text representation of this DSP effect for test failure outputs.
const DSPBase< SampleType > * operator[](long long int index) const
Accesses a specific element in the DSP sequence (immutable version)
DSPBase< SampleType > * operator[](long long int index)
Accesses a specific element in the DSP sequence (mutable version)
DSPSequence(DSPSequence &&) noexcept=default
Moves DSP chain from another DSP sequence.
void prepare(double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames) override
Prepare for processing.
virtual bool supportsEnvelopeFor(int) const override
Tells whether this effect accepts automation envelopes for a particular parameter.
std::unique_ptr< DSPBase< SampleType > > pop(long long int index=-1)
Extracts a specific element in the DSP chain by removing it.
DSPSequence(const DSPSequence &)=delete
No copy construction.
void append(DerivedDSP &&dsp)
Appends an element to the end of DSP chain.
DSPSequence & operator=(const DSPSequence &)=delete
No copy assignment.
bool supportsChannelLayout(size_t numInputChannels, size_t numOutputChannels) const override
Tells the runner (host) whether this effect supports a specific i/o configuration.
void append(std::unique_ptr< DSPBase< SampleType > > dsp)
Appends an element to the end of DSP chain.
Thrown when a container index is out of range.
Thrown when a nullptr could be handled gracefully.
#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 HART_THROW_OR_RETURN(ExceptionType, message, returnValue)
Throws an exception if HART_DO_NOT_THROW_EXCEPTIONS is set, prints a message and returns a specified ...
#define HART_DSP_DECLARE_ALIASES_FOR(ClassName)