Delay
About Delay
A delay effect is an audio processing technique used to create an echo-like repetition of a sound. It is commonly used in music production and live performances to add depth, space, and texture to a sound. The most common parameters of a delay effect include delay time, feedback, and mix. Delay time determines the length of time between the original sound and its repetition. Feedback controls the number of repetitions and their decay, allowing for a longer or shorter echo effect. The mix parameter adjusts the balance between the original sound and the delayed repetitions, allowing for a subtle or prominent delay effect in the overall mix. Other parameters may include modulation, which adds a slight pitch or time variation to the repetitions, and filtering, which shapes the frequency content of the delayed sound.
Echo vs. Delay
The main difference between echo and delay effects lies in the way they produce and manipulate repetitions of the original sound.
Echo: Echo is a natural acoustic phenomenon that occurs when sound waves bounce off surfaces and return to the listener with a time delay. In the context of audio effects, an echo effect recreates this phenomenon artificially. It produces a series of distinct and audible repetitions of the original sound, with each repetition gradually fading away. The repetitions are usually spaced apart at regular intervals, creating a rhythmic pattern. Echo effects are commonly used to add depth, spaciousness, and a sense of distance to the sound.
Delay: Delay is a more general term that encompasses various types of time-based effects. In the context of audio effects, a delay effect creates a single repetition of the original sound, which is then repeated at regular intervals. Unlike echo, the repetitions in a delay effect are often identical to the original sound, without fading away. The delay time determines the length of the interval between repetitions, and it can be adjusted to create different rhythmic patterns or to synchronize with the tempo of the music. Delay effects are widely used for creating rhythmic patterns, adding texture, and enhancing the overall sound.
In summary, while both echo and delay effects involve the repetition of sound, echo emphasizes the fading repetitions with a sense of space, while delay focuses on creating rhythmic patterns with identical repetitions.
Switchboard Editor example
This example uses the Superpowered Extension.
Why use the Superpowered Extension instead of Superpowered directly?
Code Example
- JSON
- Swift
- Kotlin
- C++
- JavaScript
{
"nodes": {
{ "id": "echoNode", "type": "Superpowered.EchoNode" }
},
"connections": {
{ "sourceNode": "inputNode", "destinationNode": "echoNode" },
{ "sourceNode": "echoNode", "destinationNode": "OutputNode" }
}
}
import SwitchboardSDK
import SwitchboardSuperpowered
class DelayExample {
let audioGraph = SBAudioGraph()
let echoNode = SBEchoNode()
let audioEngine = SBAudioEngine()
init() {
echoNode.isEnabled = true
audioGraph.addNode(echoNode)
audioGraph.connect(audioGraph.inputNode, to: echoNode)
audioGraph.connect(echoNode, to: audioGraph.outputNode)
}
}
import com.synervoz.switchboard.sdk.audioengine.AudioEngine
import com.synervoz.switchboard.sdk.audiograph.AudioGraph
import com.synervoz.switchboardsuperpowered.audiographnodes.EchoNode
class DelayExample(context: Context) {
val audioEngine = AudioEngine(context)
val echoNode = EchoNode()
val audioGraph = AudioGraph()
init {
echoNode.isEnabled = true
audioGraph.addNode(echoNode)
audioGraph.connect(audioGraph.inputNode, echoNode)
audioGraph.connect(echoNode, audioGraph.outputNode)
audioEngine.start(audioGraph)
}
}
#include "AudioGraph.hpp"
#include "EchoNode.hpp"
using namespace switchboard;
using namespace switchboard::extensions::superpowered;
class DelayExample {
public:
DelayExample() {
// Setting up node
echoNode.setEnabled(true);
// Adding nodes to audio graph
audioGraph.addNode(echoNode);
// Connecting audio nodes
audioGraph.connect(audioGraph.getInputNode(), echoNode);
audioGraph.connect(echoNode, audioGraph.getOutputNode());
// Starting the graph
audioGraph.start();
}
// Example method called by the audio processing pipeline on each buffer
bool process(float** buffers, const uint numberOfChannels, const uint numberOfFrames, const uint sampleRate) {
AudioBuffer<float> inBuffer = AudioBuffer<float>(numberOfChannels, numberOfFrames, false, sampleRate, buffers);
AudioBuffer<float> outBuffer = AudioBuffer<float>(numberOfChannels, numberOfFrames, false, sampleRate, buffers);
const bool result = audioGraph->process(&inBuffer, &outBuffer);
return result;
}
private:
AudioGraph audioGraph;
EchoNode echoNode;
};
// Change the import to reflect the location of library
// relative to this publically accessible AudioWorklet
import '../../../libs/superpowered/Superpowered.js'
class SuperpoweredEchoProcessor extends SuperpoweredWebAudio.AudioWorkletProcessor {
onReady() {
this.echo = new this.Superpowered.Echo(
this.samplerate, // the samplerate
96000 // The maximumSamplerate, the same in this case
)
this.echo.enabled = true
}
onDestruct() {
this.echo.destruct()
}
applyPreset(preset) {
for (const effectName of Object.keys(preset)) {
for (const property of Object.keys(preset[effectName])) {
this[effectName][property] = preset[effectName][property]
uiDefinitions.parameters.find((p) => p.id === property).defaultValue =
preset[effectName][property]
}
}
}
// messages are received from the main scope through this method.
onMessageFromMainScope(message) {
if (message.command === 'requestUiDefinitions') {
this.sendMessageToMainScope({ uiDefinitions: uiDefinitions })
}
if (message.command === 'applyPreset') {
this.applyPreset(message.preset)
this.sendMessageToMainScope({ updateUiDefinitions: uiDefinitions })
}
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)
}
processAudio(inputBuffer, outputBuffer, buffersize, parameters) {
this.echo.samplerate = this.samplerate
if (
!this.echo.process(inputBuffer.pointer, outputBuffer.pointer, buffersize)
)
this.Superpowered.memoryCopy(
outputBuffer.pointer,
inputBuffer.pointer,
buffersize * 8
)
}
}
registerProcessor('SuperpoweredEchoProcessor', SuperpoweredEchoProcessor)