FX Class: Echo

Interactive example


Overview

This simple Echo effect is based on delaying a signal over time. Listeners perceive an audible repetition of a signal after some duration of time.


Implementation example

The wet property is the volume of each repeat and the the dry property is the volume of the original sound. Both values can be set between 0.0 and 1.0, **or** the setMix() method can be used instead to balance between the two.

The decay property controls the tail or trail of the echo which can be set between 0 and 1. The user also has access to the bpm property (beats per minute) of the echo (between 40 and 250) and the beats property which controls the delay in beats (between 0.03125 and 2).

One instance allocates around 770 kb memory.

Usage example without the optional FX processing chain:

class SuperpoweredEchoStageProcessor extends SuperpoweredWebAudio.AudioWorkletProcessor {
onReady() {
this.echo = new this.Superpowered.Echo(
this.samplerate, // the samplerate
96000 // The maximumSamplerate, the same in this case
);
this.effect.enabled = true;
}
// Runs before the node is destroyed.
// Clean up memory and objects here (such as free allocated linear memory or destruct Superpowered objects).
onDestruct() {
this.echo.destruct();
}
// Messages are received from the main scope through this method.
onMessageFromMainScope(message) {
if (typeof(message.dry) != 'undefined') this.echo.dry = message.dry;
if (typeof(message.wet) != 'undefined') this.echo.wet = message.wet;
if (typeof(message.bpm) != 'undefined') this.echo.bpm = message.bpm;
if (typeof(message.decay) != 'undefined') this.echo.decay = message.decay;
if (typeof(message.beats) != 'undefined') this.echo.beats = message.beats;
if (typeof(message.enabled) != 'undefined') this.echo.enabled = Boolean(message.enabled);
}
// THe mai process block of the DSP
processAudio(inputBuffer, outputBuffer, buffersize, parameters) {
// Ensure the samplerate is in sync on every audio processing callback
this.echo.samplerate = this.samplerate;
// Render the output buffers
if (!this.echo.process(inputBuffer.pointer, outputBuffer.pointer, buffersize)) {
for (let n = 0; n < buffersize * 2 ; n++) outputBuffer.array[n] = inputBuffer.array[n];
}
}
}

Or, to use with an optional effect FX added to the wet signal:

class SuperpoweredEchoStageProcessor extends SuperpoweredWebAudio.AudioWorkletProcessor {
onReady() {
this.echo = new this.Superpowered.Echo(
this.samplerate,
96000
);
this.filter = new this.Superpowered.Filter(
this.Superpowered.Filter.Resonant_Lowpass,
this.samplerate
);
this.echo.enabled = true;
this.filter.frequency = 4000;
this.filter.enabled = true;
}
// Runs before the node is destroyed.
// Clean up memory and objects here (such as free allocated linear memory or destruct Superpowered objects).
onDestruct() {
this.echo.destruct();
this.filter.destruct();
}
// messages are received from the main scope through this method.
onMessageFromMainScope(message) {
if (typeof(message.dry) != 'undefined') this.echo.dry = message.dry;
if (typeof(message.wet) != 'undefined') this.echo.wet = message.wet;
if (typeof(message.bpm) != 'undefined') this.echo.bpm = message.bpm;
if (typeof(message.decay) != 'undefined') this.echo.decay = message.decay;
if (typeof(message.beats) != 'undefined') this.echo.beats = message.beats;
if (typeof(message.enabled) != 'undefined') this.echo.enabled = Boolean(message.enabled);
if (typeof(message.frequency) != 'undefined') this.filter.frequency = Number(message.frequency);
}
processAudio(inputBuffer, outputBuffer, buffersize, parameters) {
// Ensure the samplerate is in sync on every audio processing callback
this.echo.samplerate = this.samplerate;
this.filter.samplerate = this.samplerate;
// Render the output buffers
if (!this.echo.processWithFx(inputBuffer.pointer, outputBuffer.pointer, buffersize, this.filter)) {
for (let n = 0; n < buffersize * 2 ; n++) outputBuffer.array[n] = inputBuffer.array[n];
}
}
}

To setup without the optional FX processing chain

#include "SuperpoweredEcho.h"
void initEchoEffect() {
const unsigned int sampleRate = 44100;
echo = new Superpowered::Echo(sampleRate);
}
void configureEchoEffect() {
echo->dry = 0.5;
echo->wet = 42;
echo->bpm = 170;
echo->decay = 0.5;
echo->beats = 0.5;
echo->enabled = true;
}
void processAudio(float *interleavedInput, float *interleavedOutput, unsigned int numberOfFrames, unsigned int samplerate) {
// Ensure the samplerate is in sync on every audio processing callback
echo->samplerate = samplerate;
// Render the output buffers
bool outputChanged = echo->process(interleavedInput, interleavedOutput, numberOfFrames);
...
}

Or, to use with the optional FX processing chain

#include "SuperpoweredEcho.h"
void initEchoEffect() {
const unsigned int sampleRate = 44100;
const unsigned int maximumSampleRate = 96000;
echo = new Superpowered::Echo(sampleRate, maximumSampleRate);
filter = new Superpowered::Filter(Superpowered::Filter::Resonant_Lowpass, sampleRate);
}
void configureEchoEffect() {
echo->dry = 0.5;
echo->wet = 42;
echo->bpm = 170;
echo->decay = 0.5;
echo->beats = 0.5;
echo->enabled = true;
filter->frequency - 4000;
filter->enabled = true;
}
void processAudio(float *interleavedInput, float *interleavedOutput, unsigned int numberOfFrames, unsigned int samplerate) {
// Ensure the samplerate is in sync on every audio processing callback
echo->samplerate = samplerate;
filter->samplerate = samplerate;
// Render the output buffers
bool outputChanged = echo->processWithFx(interleavedInput, interleavedOutput, numberOfFrames, filter);
...
}

The optional FX processing is demonstrated below:

Properties

beats

PROPERTY
Delay between the echo sounds in beats. 0.03125 to 2.
TypeMinMaxDefault
Number
0.0312520.5

beats

PROPERTY
Delay between the echo sounds in beats. 0.03125 to 2.
TypeMinMaxDefault
float
0.0312520.5

bpm

PROPERTY
Beats per minute, the base tempo of the echo.
TypeMinMaxDefault
Number
40250128

bpm

PROPERTY
Beats per minute, the base tempo of the echo.
TypeMinMaxDefault
float
40250128

decay

PROPERTY
Decay factor of the echo sounds.
TypeMinMaxDefault
Number
00.990.5

decay

PROPERTY
Decay factor of the echo sounds.
TypeMinMaxDefault
float
00.990.5

dry

PROPERTY
Dry signal mix.
TypeMinMaxDefault
Number
011

dry

PROPERTY
Dry signal mix.
TypeMinMaxDefault
float
011

wet

PROPERTY
Wet signal mix.
TypeMinMaxDefault
Number
010.5

wet

PROPERTY
Wet signal mix.
TypeMinMaxDefault
float
010.5
Inherited from FX Class

enabled

PROPERTY
Turns the effect on/off. The actual switch will happen on the next process() call for smooth, audio-artifact free operation.
TypeMinMaxDefault
Boolean
false

enabled

PROPERTY
Turns the effect on/off. The actual switch will happen on the next process() call for smooth, audio-artifact free operation.
TypeMinMaxDefault
bool
false

samplerate

PROPERTY
The sample rate of the audio context, you must update if it changes.
TypeMinMaxDefault
Number

samplerate

PROPERTY
The sample rate of the audio context, you must update if it changes.
TypeMinMaxDefault
unsigned int

Methods

  • constructor

    METHOD
    Creates an instance of the Echo class.
    Parameters
    NameTypeDescription
    samplerateNumberThe initial sample rate in Hz.
    maximumSamplerateNumberMaximum sample rate (affects memory usage, the lower the smaller).
    Returns
    TypeDescription
    Superpowered.EchoThe constructed instance.
  • constructor

    METHOD
    Creates an instance of the Echo class.
    Parameters
    NameTypeDefaultDescription
    samplerateunsigned intThe initial sample rate in Hz.
    maximumSamplerateunsigned int96000Maximum sample rate (affects memory usage, the lower the smaller).
    Returns
    TypeDescription
    Superpowered::EchoThe constructed instance.
  • processWithFx

    METHOD
    Processes/renders the audio. Always call it in the audio processing callback, regardless if the effect is enabled or not for smooth, audio-artifact free operation. It's never blocking for real-time usage. You can change all properties and call setMix() on any thread, concurrently with process().
    Parameters
    NameTypeDescription
    inputNumber (pointer in Linear Memory)32-bit interleaved stereo input.
    outputNumber (pointer in Linear Memory)32-bit interleaved stereo output.
    numberOfFramesNumberNumber of frames to process. Recommendations for best performance: multiply of 4, minimum 64.
    fxSuperpowered.FX objectA Superpowered FX class instance, such as a Filter. fx->process() will be used to pass audio from input to the internal buffer, "coloring" the echo sounds.
    Returns
    TypeDescription
    BooleanIf process() returns with true, the contents of output are replaced with the audio output. If process() returns with false, it indicates silence. The contents of output are not changed in this case (not overwritten with zeros).
  • processWithFx

    METHOD
    Processes/renders the audio. Always call it in the audio processing callback, regardless if the effect is enabled or not for smooth, audio-artifact free operation. It's never blocking for real-time usage. You can change all properties and call setMix() on any thread, concurrently with process().
    Parameters
    NameTypeDefaultDescription
    inputfloat *32-bit interleaved stereo input.
    outputfloat *32-bit interleaved stereo output.
    numberOfFramesunsigned intNumber of frames to process. Recommendations for best performance: multiply of 4, minimum 64.
    fxSuperpowered::FX *A Superpowered FX class instance, such as a Filter. fx->process() will be used to pass audio from input to the internal buffer, "coloring" the echo sounds.
    Returns
    TypeDescription
    boolIf process() returns with true, the contents of output are replaced with the audio output. If process() returns with false, it indicates silence. The contents of output are not changed in this case (not overwritten with zeros).
  • setMix

    METHOD
    Sets dry and wet simultaneously with a good balance between them. Wet always equals to mix, but dry changes with a curve.
    Parameters
    NameTypeDescription
    mixNumberMix value >= 0 and <= 1.
    Returns
    None
  • setMix

    METHOD
    Sets dry and wet simultaneously with a good balance between them. Wet always equals to mix, but dry changes with a curve.
    Parameters
    NameTypeDefaultDescription
    mixfloatMix value >= 0 and <= 1.
    Returns
    None
Inherited from FX Class
  • destruct

    METHOD
    Destructor to free Linear Memory.
    Parameters
    None
    Returns
    None
  • process

    METHOD
    Processes/renders the audio. Always call it in the audio processing callback, regardless if the effect is enabled or not for smooth, audio-artifact free operation. It's never blocking for real-time usage.
    Parameters
    NameTypeDescription
    inputNumber (pointer in Linear Memory)32-bit interleaved stereo input.
    outputNumber (pointer in Linear Memory)32-bit interleaved stereo output.
    numberOfFramesNumberNumber of frames to process. Recommendations for best performance: multiply of 4, minimum 64.
    Returns
    TypeDescription
    BooleanIf process() returns with true, the contents of output are replaced with the audio output. If process() returns with false, it indicates silence. The contents of output are not changed in this case (not overwritten with zeros).
  • process

    METHOD
    Processes/renders the audio. Always call it in the audio processing callback, regardless if the effect is enabled or not for smooth, audio-artifact free operation. It's never blocking for real-time usage. You can change all effect properties on any thread, concurrently with process().
    Parameters
    NameTypeDefaultDescription
    inputfloat *32-bit interleaved stereo input.
    outputfloat *32-bit interleaved stereo output.
    numberOfFramesunsigned intNumber of frames to process. Recommendations for best performance: multiply of 4, minimum 64.
    Returns
    TypeDescription
    boolIf process() returns with true, the contents of output are replaced with the audio output. If process() returns with false, it indicates silence. The contents of output are not changed in this case (not overwritten with zeros).
v2.7.2