HART  0.1.0
High level Audio Regression and Testing
Loading...
Searching...
No Matches
DSP< SampleType > Class Template Referenceabstract

Base for DSP effects. More...

#include <hart_dsp.hpp>

Inheritance diagram for DSP< SampleType >:

Public Member Functions

virtual void prepare (double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames)=0
 Prepare for processing.
 
virtual void process (const AudioBuffer< SampleType > &input, AudioBuffer< SampleType > &output, const EnvelopeBuffers &envelopeBuffers)=0
 Processes the audio.
 
virtual void reset ()=0
 Resets to initial state.
 
virtual void setValue (int paramId, double value)=0
 Sets DSP value.
 
virtual double getValue (int paramId) const =0
 Retreives DSP value.
 
virtual bool supportsChannelLayout (size_t numInputChannels, size_t numOutputChannels) const =0
 Tells the runner (host) whether this effect supports a specific i/o configuration.
 
virtual void represent (std::ostream &stream) const =0
 Makes a text representation of this DSP effect for test failure outputs.
 
virtual bool supportsEnvelopeFor (int) const
 Tells whether this effect accepts automation envelopes for a particular parameter.
 
virtual bool supportsSampleRate (double) const
 Tells whether this effect supports given sample rate.
 
virtual std::unique_ptr< DSP< SampleType > > copy () const =0
 Returns a smart pointer with a copy of this object.
 
virtual std::unique_ptr< DSP< SampleType > > move ()=0
 Returns a smart pointer with a moved instance of this object.
 
virtual ~DSP ()=default
 Destructor.
 
 DSP ()=default
 Default constructor.
 
 DSP (const DSP &other)
 Copies from another DSP effect instance.
 
 DSP (DSP &&other) noexcept
 Move constructor.
 
DSPoperator= (const DSP &other)
 Copies from another DSP effect instance.
 
DSPoperator= (DSP &&other) noexcept
 Move assignment.
 
DSPwithEnvelope (int paramId, Envelope &&envelope)
 Adds envelope to a specific parameter by moving it.
 
DSPwithEnvelope (int paramId, const Envelope &envelope)
 Adds envelope to a specific parameter by copying it.
 
bool hasEnvelopeFor (int paramId)
 Checks if there's an automation envelope attached to a specific parameter.
 
void prepareWithEnvelopes (double sampleRateHz, size_t numInputChannels, size_t numOutputChannels, size_t maxBlockSizeFrames)
 Prepares all the attached envelopes and the effect itself for processing.
 
void processWithEnvelopes (const AudioBuffer< SampleType > &input, AudioBuffer< SampleType > &output)
 Renders all the automation envelopes and processes the audio.
 

Related Symbols

(Note that these are not member symbols.)

template<typename SampleType >
std::ostream & operator<< (std::ostream &stream, const DSP< SampleType > &dsp)
 Prints readable text representation of the DSP object into the I/O stream.
 

Detailed Description

template<typename SampleType>
class hart::DSP< SampleType >

Base for DSP effects.

This class is used both for adapting your DSP classes that you wish to test, and for using in DSP chains of Signals, so you can use stock effects like GainDb as tested processors, and you can use your tested DSP subclasses in Signals' DSP chains with other effects. You can even chain multiple of your own DSP classes together this way. All the callbacks of this class are guaranteed to be called from the same thread.

Template Parameters
SampleTypeType of values that will be processed, typically float or double

Definition at line 33 of file hart_dsp.hpp.

Constructor & Destructor Documentation

◆ ~DSP()

template<typename SampleType >
virtual ~DSP ( )
virtualdefault

Destructor.

◆ DSP() [1/3]

template<typename SampleType >
DSP ( )
default

Default constructor.

◆ DSP() [2/3]

template<typename SampleType >
DSP ( const DSP< SampleType > &  other)
inline

Copies from another DSP effect instance.

Attached automation envelopes are deep-copied

Definition at line 139 of file hart_dsp.hpp.

◆ DSP() [3/3]

template<typename SampleType >
DSP ( DSP< SampleType > &&  other)
inlinenoexcept

Move constructor.

Attached automation envelopes are moved as well

Definition at line 147 of file hart_dsp.hpp.

Member Function Documentation

◆ prepare()

template<typename SampleType >
virtual void prepare ( double  sampleRateHz,
size_t  numInputChannels,
size_t  numOutputChannels,
size_t  maxBlockSizeFrames 
)
pure virtual

Prepare for processing.

In real-time DSP, such methods are usually used for allocating memory and other non-realtime-safe and heavyweight operations. But keep in mind that that HART does not do real-time processing, so this merely follows common real-time DSP design conventions, where non-realtime operations are done in a separate callback like this one. This method is guaranteed to be called after supportsChannelLayout() and supportsSampleRate(), but before process(). It is guaranteed that the number of input and output channels obeys supportsChannelLayout() and supportsSampleRate() preferences. It is guaranteed that all subsequent process() calls will be in line with the arguments received in this callback.

Parameters
sampleRateHzsample rate at which the audio should be interpreted and processed
numInputChannelsNumber of input channels
numOutputChannelsNumber of output channels
maxBlockSizeFramesMaximum block size in frames (samples)

Implemented in GainDb< SampleType >, GainLinear< SampleType >, and HardClip< SampleType >.

◆ process()

template<typename SampleType >
virtual void process ( const AudioBuffer< SampleType > &  input,
AudioBuffer< SampleType > &  output,
const EnvelopeBuffers envelopeBuffers 
)
pure virtual

Processes the audio.

Depending on circumstances, this callback will either be called once to process an entire piece of audio from start to finish, or called repeatedly, one block at a time (see AudioTestBuilder::withBlockSize()). All audio blocks except the last one are guaranteed to be equal to maxBlockSizeFrames set in prepare() callback. It is guaranteed that input and output buffers are equal in length in frames (samples) to each, but they might have different number of channels. Use supportsChannelLayout() to indicate whether the effect supports a specific i/o configuration or not, as it will be called before prepare(). It is guaranteed that envelopeBuffers will only contain the values for all attached envelopes for this instance of DSP effect, and will not contain any data (including key with empty item) if there's no envelope attached to a specific parameter ID in this effects's instance. It will never contain envelopes for IDs that get rejected by supportsEnvelopeFor().

Note
This method may be called in a replacing manner, i. e. input and output may be references to the same object.
Warning
Remember that the very last block of audio is almost always smaller than the block size set in prepare(), so be careful with buffer bounds.
Note
Note that this method does not have to be real-time safe, as all rendering always happens offline. Also note that, unlike real-time audio applications, this method is called on the same thread as all others like prepare().
Parameters
inputInput audio block
outputOutput audio block
envelopeBuffersEnvelope values for this block, see EnvelopeBuffers

Implemented in HardClip< SampleType >, GainDb< SampleType >, and GainLinear< SampleType >.

◆ reset()

template<typename SampleType >
virtual void reset ( )
pure virtual

Resets to initial state.

Ideally should be implemented in a way that audio produced after resetting is identical to audio produced after instantiation

Implemented in GainDb< SampleType >, GainLinear< SampleType >, and HardClip< SampleType >.

◆ setValue()

template<typename SampleType >
virtual void setValue ( int  paramId,
double  value 
)
pure virtual

Sets DSP value.

Parameters
paramIdSome ID that your subclass understands; use of enums is encouraged for readability
valueValue of the param in an appropriate unit; use of SI units is enocuraged (i.e. s instead of ms. Hz instead of kHz) to make better use of unit literals (see Units)
Warning
This method is only called to set a fixed value before processing, and is not called to do automation (via hart::Envelope) If you want your class to support automation for a specific parameter, override supportsEnvelopeFor(), and then use envelopeBuffers provided in process() callback.

Implemented in GainDb< SampleType >, GainLinear< SampleType >, and HardClip< SampleType >.

◆ getValue()

template<typename SampleType >
virtual double getValue ( int  paramId) const
pure virtual

Retreives DSP value.

Among other things, it can be used to retreive various readings like Gain Reduction measurements from your effect for further inspection

Parameters
paramIdSome ID that your subclass understands
Returns
The value of requested parameter in a unit that your subclass understands
Note
This method is only intended for parameters that don't have an automation envelope attached to this specific instance. To get values for automated parameters, use envelopeBuffers provided in process() callback.

Implemented in GainDb< SampleType >, GainLinear< SampleType >, and HardClip< SampleType >.

◆ supportsChannelLayout()

template<typename SampleType >
virtual bool supportsChannelLayout ( size_t  numInputChannels,
size_t  numOutputChannels 
) const
pure virtual

Tells the runner (host) whether this effect supports a specific i/o configuration.

It is guaranteed that the effect will not receive unsupported number of channels in process(). However, it is not always to handle gracefully channel layout being unsupported, so in some circumstances it can cause an exception or a test failure. This method is guaranteed to be called at least once before prepare()

Implemented in GainDb< SampleType >, GainLinear< SampleType >, and HardClip< SampleType >.

◆ represent()

template<typename SampleType >
virtual void represent ( std::ostream &  stream) const
pure virtual

Makes a text representation of this DSP effect for test failure outputs.

It is strongly encouraged to follow python's repr() conventions for returned text - basically, put something like "MyClass(value1, value2)" (with no quotes) into the stream whenever possible, or "<Readable info in angled brackets>" otherwise. Also, use built-in stream manipulators like dbPrecision wherever applicable. Use HART_DEFINE_GENERIC_REPRESENT() to get a basic implementation for this method.

Parameters
[out]streamOutput stream to write to

Implemented in GainDb< SampleType >, GainLinear< SampleType >, and HardClip< SampleType >.

◆ supportsEnvelopeFor()

template<typename SampleType >
virtual bool supportsEnvelopeFor ( int  ) const
inlinevirtual

Tells whether this effect accepts automation envelopes for a particular parameter.

Parameters
paramIdSome ID that your subclass understands
Returns
true if your subclass can process automation for this parameter, false otherwise

Reimplemented in GainDb< SampleType >, GainLinear< SampleType >, and HardClip< SampleType >.

Definition at line 110 of file hart_dsp.hpp.

◆ supportsSampleRate()

template<typename SampleType >
virtual bool supportsSampleRate ( double  ) const
inlinevirtual

Tells whether this effect supports given sample rate.

It is guaranteed to be called before prepare()

Parameters
sampleRateHzSample rate in question
Returns
true if effect is capable of interpreting and processing in a given sample rate, false otherwise

Definition at line 116 of file hart_dsp.hpp.

◆ copy()

template<typename SampleType >
virtual std::unique_ptr< DSP< SampleType > > copy ( ) const
pure virtual

Returns a smart pointer with a copy of this object.

Just put one of those two macros into your class body, and your copy() and move() are sorted:

Read their description, and choose one that fits your class. You can, of course, make your own implementation, but you're not supposed to, unless you're doing something obscure.

◆ move()

template<typename SampleType >
virtual std::unique_ptr< DSP< SampleType > > move ( )
pure virtual

Returns a smart pointer with a moved instance of this object.

Just pick a macro to define it - see description for copy() for details

◆ operator=() [1/2]

template<typename SampleType >
DSP & operator= ( const DSP< SampleType > &  other)
inline

Copies from another DSP effect instance.

Attached automation envelopes are deep-copied

Definition at line 154 of file hart_dsp.hpp.

◆ operator=() [2/2]

template<typename SampleType >
DSP & operator= ( DSP< SampleType > &&  other)
inlinenoexcept

Move assignment.

Attached automation envelopes are moved as well

Definition at line 167 of file hart_dsp.hpp.

◆ withEnvelope() [1/2]

template<typename SampleType >
DSP & withEnvelope ( int  paramId,
Envelope &&  envelope 
)
inline

Adds envelope to a specific parameter by moving it.

Guaranteed to be called strictly after the supportsEnvelopeFor() callback, and only if it has returned true for this specific paramId. Can be chained together like myEffect.withEnvelope (someId, someEnvelope).withEnvelope (otherId, otherEnvelope). If called multiple times for the same paramId, only last envelope for this ID will be used, all previous ones will be descarded.

Parameters
paramIdSome ID that your subclass understands
envelopeEnvelope to be attached
Returns
Reference to itself for chaining

Definition at line 183 of file hart_dsp.hpp.

◆ withEnvelope() [2/2]

template<typename SampleType >
DSP & withEnvelope ( int  paramId,
const Envelope envelope 
)
inline

Adds envelope to a specific parameter by copying it.

Guaranteed to be called strictly after the supportsEnvelopeFor() callback, and only if it has returned true for this specific paramId. Can be chained together like myEffect.withEnvelope (someId, someEnvelope).withEnvelope (otherId, otherEnvelope). If called multiple times for the same paramId, only last envelope for this ID will be used, all previous ones will be descarded.

Parameters
paramIdSome ID that your subclass understands
envelopeEnvelope to be attached
Returns
Reference to itself for chaining

Definition at line 200 of file hart_dsp.hpp.

◆ hasEnvelopeFor()

template<typename SampleType >
bool hasEnvelopeFor ( int  paramId)
inline

Checks if there's an automation envelope attached to a specific parameter.

The envelopes are guaranteed to be attached strictly before prepare() callback, so by the time of the first process() call consider the presence or absence of envelope permanent.

Returns
Reference to itself for chaining

Definition at line 214 of file hart_dsp.hpp.

◆ prepareWithEnvelopes()

template<typename SampleType >
void prepareWithEnvelopes ( double  sampleRateHz,
size_t  numInputChannels,
size_t  numOutputChannels,
size_t  maxBlockSizeFrames 
)
inline

Prepares all the attached envelopes and the effect itself for processing.

This method is intended to be called by DSP hosts like hart::AudioTestBuilder or hart::Signal. If you're making something that owns an instance of a DSP and needs it to generate audio, you must call this method before calling processWithEnvelopes(). You must also call supportsChannelLayout() and supportsSampleRate() before calling this method.

Attention
If you're not making a custom host, you probably don't need to call this method.

Definition at line 225 of file hart_dsp.hpp.

◆ processWithEnvelopes()

template<typename SampleType >
void processWithEnvelopes ( const AudioBuffer< SampleType > &  input,
AudioBuffer< SampleType > &  output 
)
inline

Renders all the automation envelopes and processes the audio.

This method is intended to be called by DSP hosts like hart::AudioTestBuilder hart::Signal. If you're making something that owns an instance of a Signal and needs it to generate audio, you must call it after calling prepareWithEnvelopes().

Attention
If you're not making a custom host, you probably don't need to call this method.
Parameters
inputInput audio block
outputOutput audio block

Definition at line 260 of file hart_dsp.hpp.


The documentation for this class was generated from the following file: