Aviate Audio Multiverse Library
LibBasicFunctions.h
Go to the documentation of this file.
1 /**************************************************************************/
13 #include <cstddef>
14 #include <new>
15 #include <atomic>
16 #include <cmath>
17 
18 #include <arm_math.h>
19 #include "sysPlatform/SysTypes.h"
20 #include "sysPlatform/AudioStream.h"
21 
22 #include "Aviate/Aviate.h"
23 #include "Aviate/AviateTypes.h"
24 #include "Aviate/ForwardDeclares.h"
25 
26 #ifndef AVIATE_LIBBASICFUNCTIONS_H_
27 #define AVIATE_LIBBASICFUNCTIONS_H_
28 
29 namespace Aviate {
30 
32 extern const size_t AUDIO_BLOCK_SIZE_BYTES;
33 
34 /**************************************************************************/
40  int offset;
41  int index;
42 };
43 
49 
55 
60 size_t AVIATE_API calcAudioSamples(float milliseconds);
61 
65 float AVIATE_API calcAudioTimeMs(size_t numSamples);
66 
73 
77 void AVIATE_API clearAudioBlock(audio_block_t *block);
78 
86 void AVIATE_API alphaBlend(audio_block_t *out, audio_block_t *dry, audio_block_t* wet, float mix);
87 
95 void AVIATE_API gainAdjust(audio_block_t *out, audio_block_t *in, float vol, int coeffShift = 0);
96 
103 void AVIATE_API combine(audio_block_t *out, audio_block_t *in0, audio_block_t *in1);
104 
109 float AVIATE_API calcVolumeExp(float volumeIn);
110 
118 float AVIATE_API convertLinearToLogPow(float inputValue, float midpoint = 0.8f);
119 
123 float AVIATE_API log2Fast(float input);
124 
128 float AVIATE_API log10Fast(float input);
129 
133 float AVIATE_API dbfsFast(int16_t inputAbs);
134 
138 float dbfsFast(float inputAbs);
139 
143 uint16_t AVIATE_API getPeakAbsIntegerValue(const int16_t* audioDataPtr);
144 
151 template<typename T>
152 T AVIATE_API saturate(T val, T min, T max) {
153  if (val < min) { return min; }
154  if (val > max) { return max; }
155  return val;
156 }
157 
158 /**************************************************************************/
172 public:
173  AudioDelay() = delete;
174 
178  AudioDelay(size_t maxSamples);
179 
183  AudioDelay(float maxDelayTimeMs);
184 
187  //AudioDelay(baCore::ExtMemSlot *slot);
189 
191  virtual ~AudioDelay();
192 
198  audio_block_t *addBlock(audio_block_t *blockIn);
199 
204  audio_block_t *getBlock(size_t index);
205 
211 
219  bool getSamples(audio_block_t *dest, size_t offsetSamples, size_t numSamples = AUDIO_SAMPLES_PER_BLOCK);
220 
228  bool getSamples(int16_t *dest, size_t offsetSamples, size_t numSamples);
229 
230 
241  bool interpolateDelay(int16_t *extendedSourceBuffer, int16_t *destBuffer, float fraction, size_t numSamples = AUDIO_SAMPLES_PER_BLOCK);
242 
247 
252 
257 
258 private:
259 
261  enum class MemType : unsigned {
262  MEM_INTERNAL = 0,
263  MEM_EXTERNAL
264  };
265 
266  MemType m_type;
267  RingBuffer<audio_block_t *> *m_ringBuffer = nullptr;
268  SramMemSlot *m_slot = nullptr;
269  size_t m_maxDelaySamples = 0;
270  bool m_getSamples(int16_t *dest, size_t offsetSamples, size_t numSamples);
271 };
272 
273 /**************************************************************************/
283 public:
284  IirBiQuadFilter() = delete;
290  IirBiQuadFilter(unsigned numStages, const int32_t *coeffs, int coeffShift = 0);
291 
293  virtual ~IirBiQuadFilter();
294 
300  void changeFilterCoeffs(unsigned numStages, const int32_t *coeffs, int coeffShift = 0);
301 
308  bool process(int16_t *output, int16_t *input, size_t numSamples);
309 private:
310  const unsigned NUM_STAGES;
311  int32_t *m_coeffs = nullptr;
312 
313  // ARM DSP Math library filter instance
314  arm_biquad_casd_df1_inst_q31 m_iirCfg;
315  int32_t *m_state = nullptr;
316 };
317 
318 /**************************************************************************/
324 public:
325  IirBiQuadFilterHQ() = delete;
331  IirBiQuadFilterHQ(unsigned maxNumStages, const int32_t *coeffs, int coeffShift = 0);
334 
340  void changeFilterCoeffs(unsigned numStages, const int32_t *coeffs, int coeffShift = 0);
341 
348  bool process(int16_t *output, int16_t *input, size_t numSamples);
349 private:
350  const unsigned NUM_STAGES;
351  int32_t *m_coeffs = nullptr;
352 
353  // ARM DSP Math library filter instance
354  arm_biquad_cas_df1_32x64_ins_q31 m_iirCfg;
355  int64_t *m_state = nullptr;
356 };
357 
358 /**************************************************************************/
364 public:
365  IirBiQuadFilterFloat() = delete;
366 
371  IirBiQuadFilterFloat(unsigned maxNumStages, const float *coeffs);
373 
378  void changeFilterCoeffs(unsigned numStages, const float *coeffs);
379 
386  bool process(float *output, float *input, size_t numSamples);
387 private:
388  const unsigned NUM_STAGES;
389  float *m_coeffs = nullptr;
390 
391  // ARM DSP Math library filter instance
392  arm_biquad_cascade_df2T_instance_f32 m_iirCfg;
393  float *m_state = nullptr;
394 
395 };
396 
397 /**************************************************************************/
401 template <typename T>
403 {
404 public:
406  enum class Function : unsigned {
407  NOT_CONFIGURED = 0,
408  HOLD,
409  LINEAR,
410  EXPONENTIAL,
411  LOGARITHMIC,
412  PARABOLIC,
413  LOOKUP_TABLE
414  };
416 
422  ParameterAutomation(T startValue, T endValue, size_t durationSamples, Function function = Function::LINEAR);
423 
429  ParameterAutomation(T startValue, T endValue, float durationMilliseconds, Function function = Function::LINEAR);
431 
437  void reconfigure(T startValue, T endValue, size_t durationSamples, Function function = Function::LINEAR);
438 
444  void reconfigure(T startValue, T endValue, float durationMilliseconds, Function function = Function::LINEAR);
445 
447  void trigger();
448 
452 
455  bool isFinished();
456 
457 private:
458  Function m_function;
459  T m_startValue;
460  T m_endValue;
461  bool m_running = false;
462  float m_currentValueX;
463  size_t m_duration;
464  //float m_coeffs[3]; ///< some general coefficient storage
465  float m_slopeX;
466  float m_scaleY;
467  bool m_positiveSlope = true;
468 };
469 
470 
471 constexpr int MAX_PARAMETER_SEQUENCES = 32;
472 
476 template <typename T>
478 {
479 public:
480  ParameterAutomationSequence() = delete;
481 
486 
493  void setupParameter(int index, T startValue, T endValue, size_t durationSamples, typename ParameterAutomation<T>::Function function);
494 
501  void setupParameter(int index, T startValue, T endValue, float durationMilliseconds, typename ParameterAutomation<T>::Function function);
502 
504  void trigger();
505 
509 
512  bool isFinished();
513 
514 private:
516  int m_currentIndex = 0;
517  int m_numStages = 0;
518  bool m_running = false;
519 };
520 
522 enum class Waveform : unsigned {
523  SINE,
524  TRIANGLE,
525  SQUARE,
526  SAWTOOTH,
527  RANDOM,
528  NUM_WAVEFORMS,
529 };
530 
531 /**************************************************************************/
538 template <class T>
540 public:
543 
548 
551  void setWaveform(Waveform waveform);
552 
555  void setRateAudio(float frequencyHz);
556 
559  void setRateRatio(float ratio);
560 
565  void setRoundnessFactor(float roundness);
566 
570 
571 private:
572  void m_updatePhase();
573  void m_initPhase(T radiansPerSample);
574  Waveform m_waveform = Waveform::SINE;
575  T* m_phaseVec = nullptr;
576  T m_radiansPerBlock = 0.0f;
577  T m_radiansPerSample = 0.0f;
578  T* m_outputVec = nullptr;
579 
580  std::atomic_flag m_phaseLock = ATOMIC_FLAG_INIT;
581  float m_roundness = 0.01f;
582 
583  static constexpr unsigned NUM_RANDOM_SEGMENTS = 4;
584  static constexpr float RANDOM_SLEW_FACTOR = 0.001f;
585 
586  unsigned m_previousPhaseSegment = 0;
587  float m_randTargetValue;
588  float m_accumulator = 0.0f;
589 
590  const T PI_F = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899;
591  const T TWO_PI_F = 2.0 * 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899;
592  const T PI_DIV2_F = 0.5 * 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899;
593  const T THREE_PI_DIV2_F = 1.5 * 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899;
594  const T TRIANGE_POS_SLOPE = 2.0f/PI_F;
595  const T TRIANGE_NEG_SLOPE = -2.0f/PI_F;
596  const T SAWTOOTH_SLOPE = 1.0f/PI_F;
597 };
598 
599 /**************************************************************************/
609 public:
610 
612  virtual ~Compressor();
613 
619  bool processFloat(float *output, float *input, size_t numSamples);
620 
623  void setInputGain(float gain);
624 
627  void setThresholdDb(float thresholdDb);
630  void setRatio(float ratio);
631 
634  void setAttackMs(unsigned attackMs);
635 
638  void setReleaseMs(unsigned releaseMs);
639 
640 private:
641 
642  // Parameters
643  float m_thresholdDb = 0;
644  float m_ratio = 0;
645  float m_inputGain = 0;
646  float m_attackMs = 0;
647  float m_releaseMs = 0;
648 
649  // Storage variables
650  float m_ratioInv = 0;
651  float m_threshold = 0;
652  float m_gainRelease = 0;
653  float m_gainAttack = 0;
654  float m_prevEnvelope = 0;
655  float m_compGain = 0;
656 };
657 
658 } // namespace Aviate
659 
660 
661 #endif /* AVIATE_LIBBASICFUNCTIONS_H_ */
#define AVIATE_API
enable default visibility. This is used for public API functions and classes.
Definition: Aviate.h:19
Audio delays are a very common function in audio processing.
Definition: LibBasicFunctions.h:171
virtual ~AudioDelay()
Destrutor.
RingBuffer< audio_block_t * > * getRingBuffer() const
When using INTERNAL memory, this function can return a pointer to the underlying baCore::RingBuffer t...
bool interpolateDelay(int16_t *extendedSourceBuffer, int16_t *destBuffer, float fraction, size_t numSamples=AUDIO_SAMPLES_PER_BLOCK)
Provides linearly interpolated samples between discrete samples in the sample buffer....
bool getSamples(audio_block_t *dest, size_t offsetSamples, size_t numSamples=AUDIO_SAMPLES_PER_BLOCK)
Retrieve an audio block (or samples) from the buffer into a destination block.
bool getSamples(int16_t *dest, size_t offsetSamples, size_t numSamples)
Retrieve an audio block (or samples) from the buffer into a destination sample array.
SramMemSlot * getSlot() const
When using EXTERNAL memory, this function can return a pointer to the underlying baCore::ExtMemSlot o...
size_t getMaxDelaySamples()
Returns the max possible delay samples. For INTERNAL memory, the delay can be equal to the full maxVa...
audio_block_t * addBlock(audio_block_t *blockIn)
Add a new audio block into the buffer. When the buffer is filled, adding a new block will push out th...
AudioDelay(SramMemSlot *slot)
Construct an audio buffer using a slot configured with the baCore::ExternalSramManager.
AudioDelay(float maxDelayTimeMs)
Construct an audio buffer using INTERNAL memory by specifying the max amount of time you will want av...
AudioDelay(size_t maxSamples)
Construct an audio buffer using INTERNAL memory by specifying the max number of audio samples you wil...
audio_block_t * getBlock(size_t index)
When using INTERNAL memory, returns the pointer for the specified index into buffer.
bool setSpiDmaCopyBuffer(void)
Calling this function will force the underlying SPI DMA to use an extra copy buffer....
Simple Compressor.
Definition: LibBasicFunctions.h:608
virtual ~Compressor()
destructor
void setReleaseMs(unsigned releaseMs)
set the compressor release in milliseconds
void setInputGain(float gain)
set the compressors input gain
bool processFloat(float *output, float *input, size_t numSamples)
process an array of floating point samples
void setAttackMs(unsigned attackMs)
set the comrpessor attack in milliseconds
Compressor()
constructor
void setThresholdDb(float thresholdDb)
set the compressors threshold in dB
void setRatio(float ratio)
set the compressor ratio
A single-precision floating-point biquad using CMSIS-DSP hardware instructions.
Definition: LibBasicFunctions.h:363
virtual ~IirBiQuadFilterFloat()
Destructor.
IirBiQuadFilterFloat(unsigned maxNumStages, const float *coeffs)
Construct a Biquad filter with specified number of stages and coefficients.
bool process(float *output, float *input, size_t numSamples)
Process the data using the configured IIR filter.
void changeFilterCoeffs(unsigned numStages, const float *coeffs)
Reconfigure the filter coefficients.
A High-precision version of IirBiQuadFilter often necessary for complex, multistage filters.
Definition: LibBasicFunctions.h:323
virtual ~IirBiQuadFilterHQ()
Destructor.
void changeFilterCoeffs(unsigned numStages, const int32_t *coeffs, int coeffShift=0)
Reconfigure the filter coefficients.
IirBiQuadFilterHQ(unsigned maxNumStages, const int32_t *coeffs, int coeffShift=0)
Construct a Biquad filter with specified number of stages, coefficients and scaling.
bool process(int16_t *output, int16_t *input, size_t numSamples)
Process the data using the configured IIR filter.
IIR BiQuad Filter - Direct Form I y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 *...
Definition: LibBasicFunctions.h:282
void changeFilterCoeffs(unsigned numStages, const int32_t *coeffs, int coeffShift=0)
Reconfigure the filter coefficients.
bool process(int16_t *output, int16_t *input, size_t numSamples)
Process the data using the configured IIR filter.
IirBiQuadFilter(unsigned numStages, const int32_t *coeffs, int coeffShift=0)
Construct a Biquad filter with specified number of stages, coefficients and scaling.
virtual ~IirBiQuadFilter()
Destructor.
The LFO is commonly used on modulation effects where some parameter (delay, volume,...
Definition: LibBasicFunctions.h:539
void setRateAudio(float frequencyHz)
Set the LFO rate in Hertz.
LowFrequencyOscillatorVector(Waveform waveform)
Specifies the desired waveform at construction time.
LowFrequencyOscillatorVector()
Default constructor, uses SINE as default waveform.
T * getNextVector()
Get the next waveform value.
virtual ~LowFrequencyOscillatorVector()
destructor
void setRoundnessFactor(float roundness)
This value will control how much roundness is applied to sharp transition points in the waveform....
void setWaveform(Waveform waveform)
Change the waveform.
void setRateRatio(float ratio)
Set the LFO rate as a fraction.
This class allows you to create a sequence of automations where each stage has it's own configuration...
Definition: LibBasicFunctions.h:478
bool isFinished()
check if the automation is finished
void trigger()
Trigger a the automation sequence until numStages is reached or a Function is ParameterAutomation<T>:...
T getNextValue()
get the next value in the automation sequence
void setupParameter(int index, T startValue, T endValue, size_t durationSamples, typename ParameterAutomation< T >::Function function)
Configure one of the stages in the automation sequence.
virtual ~ParameterAutomationSequence()
destructor
ParameterAutomationSequence(int numStages)
Construction an automation sequence with the specified number of stages.
void setupParameter(int index, T startValue, T endValue, float durationMilliseconds, typename ParameterAutomation< T >::Function function)
Configure one of the stages in the automation sequence.
The class will automate a parameter using a trigger from a start value to an end value,...
Definition: LibBasicFunctions.h:403
void reconfigure(T startValue, T endValue, float durationMilliseconds, Function function=Function::LINEAR)
set the start and end values for the automation
ParameterAutomation()
Default constructor.
ParameterAutomation(T startValue, T endValue, float durationMilliseconds, Function function=Function::LINEAR)
Construct an automation object based on duration in audio samples.
virtual ~ParameterAutomation()
destructor
void trigger()
Start the automation from startValue.
Function
Type of function to control automation.
Definition: LibBasicFunctions.h:406
ParameterAutomation(T startValue, T endValue, size_t durationSamples, Function function=Function::LINEAR)
Construct an automation object based on duration in audio samples.
bool isFinished()
check if automation is completed
void reconfigure(T startValue, T endValue, size_t durationSamples, Function function=Function::LINEAR)
set the start and end values for the automation
T getNextValue()
Retrieve the next calculated automation value.
This object is used for data transfers to/from the external SPI SRAM.
Definition: SramManager.h:28
The Aviate library/namespace provides the primary API for working with Multiverse.
Definition: AudioEffectWrapper.h:24
size_t AVIATE_API calcAudioSamples(float milliseconds)
Calculate the number of audio samples (rounded up) that correspond to a given length of time.
void AVIATE_API combine(audio_block_t *out, audio_block_t *in0, audio_block_t *in1)
Combine two audio blocks through vector addition out[n] = in0[n] + in1[n].
void AVIATE_API alphaBlend(audio_block_t *out, audio_block_t *dry, audio_block_t *wet, float mix)
Perform an alpha blend between to audio blocks. Performs out = dry*(1-mix) + wet*(mix)
float AVIATE_API dbfsFast(int16_t inputAbs)
Fast convert 16-bit positive audio sample to dbFS value (decibal fullscale)
float AVIATE_API log10Fast(float input)
Fast log10() implementation.
const size_t AUDIO_BLOCK_SIZE_BYTES
size of an audio block in bytes
void AVIATE_API clearAudioBlock(audio_block_t *block)
Clear the contents of an audio block to zero.
float AVIATE_API calcAudioTimeMs(size_t numSamples)
Calculate a length of time in milliseconds from the number of audio samples.
void AVIATE_API gainAdjust(audio_block_t *out, audio_block_t *in, float vol, int coeffShift=0)
Applies a gain to the audio via fixed-point scaling according to out = int * (vol * 2^coeffShift)
Waveform
Supported LFO waveforms.
Definition: LibBasicFunctions.h:522
@ SQUARE
square wave
@ RANDOM
a non-repeating random waveform
@ TRIANGLE
triangle wave
@ SAWTOOTH
sawtooth wave
@ NUM_WAVEFORMS
the number of defined waveforms
uint16_t AVIATE_API getPeakAbsIntegerValue(const int16_t *audioDataPtr)
get the peak absolute value as from an audio block
float AVIATE_API calcVolumeExp(float volumeIn)
Calculate an exponential volume from a linear volume. E.g. convert a linear volume curve to an expone...
size_t AVIATE_API calcOffset(QueuePosition position)
Calculate the number of audio samples (usually an offset) from a queue position.
float AVIATE_API log2Fast(float input)
Fast log2() implementation.
constexpr int MAX_PARAMETER_SEQUENCES
Maximum number of automation sequences.
Definition: LibBasicFunctions.h:471
float AVIATE_API convertLinearToLogPow(float inputValue, float midpoint=0.8f)
Apply a non-linear taper to a normalized control. Input value must be between [0.0,...
T AVIATE_API saturate(T val, T min, T max)
min/max function
Definition: LibBasicFunctions.h:152
QueuePosition AVIATE_API calcQueuePosition(float milliseconds)
Calculate the exact sample position in an array of audio blocks that corresponds to a particular offs...
QueuePosition is used for storing the index (in an array of queues) and the offset within an audio_bl...
Definition: LibBasicFunctions.h:39
int index
index in an array of audio data blocks
Definition: LibBasicFunctions.h:41
int offset
offset in samples within an audio_block_t data buffer
Definition: LibBasicFunctions.h:40