Hz.Delay implements an interpolating,
variable-length delay. Its sibling Hz.Echo
is built atop Hz.Delay
and streamlines setup of feedback loops.
In this example, we explore the use of Hz.Delay
in a feedback network.
As seen in the graph below, we route the output of our mono oscillator
to the left channel and to the right channel we route a delayed and
fed-back version of the oscillator signal. Note the the delay node
has two inputs, one from the oscillator and the other from fb
which itself receives its input from delay
. Here's the line
of code from delay.js
that introduces the cycle:
scene.Chain(delay, feedback, delay); // our feedback loop
The Hz.Delay reference page discusses how we remedy this graph cycle.
delay.js
console.notice(`
This example uses Hz.Delay to produce a stereo echo effect. Notice
the feedback loop in the audio graph at node "fb". These are forbidden
unless the graph cycle can be broken at a Hz.Delay (or other splittable)
node.
`);
let id = `t${this.GetId()}`;
let scene = await Ascene.BeginFiber(this);
let osc = scene.NewAnode("Hz.Osc", {name:"osc", cfg:"mono"});
let delay = scene.NewAnode("Hz.Delay", {name:"delay", preset:{maxDelay:2.0}});
let feedback = scene.NewAnode("Hz.Mix", {name: "fb", cfg: "mono"});
let panL = scene.NewAnode("Hz.Mix", {name:"panL", cfg:"1to2"});
let panR = scene.NewAnode("Hz.Mix", {name:"panR", cfg:"1to2"});
let mix = scene.NewAnode("Hz.Mix", {name:"mix", cfg:"stereo"});
let dac = scene.GetDAC()
scene.verbose = 0;
scene.Chain(osc, panL, mix, dac); // clean
scene.Chain(osc, delay, panR, mix, dac);
scene.Chain(delay, feedback, delay); // our feedback loop
let agraph = scene.GetGraph();
scene.VisualizeGraph("voices/delay.js"); // before Sync/conpilation
await scene.Sync();
// scene.VisualizeGraph("voices/delay.js"); // after cycle remediation
panL.SetParam("Pan", 0);
panR.SetParam("Pan", 1);
osc.SetParam("/adsr/T", 6); // seconds of tail for the echo
feedback.SetParam("Gain", -6); // decibels
delay.SetParam("Delay", 1); // one second delay
await scene.Sync();
for(let i=0;i<10;i++)
{
let n = 50 + Math.floor(30*Math.random());
console.log("Note " + n);
osc.NoteOn(n, .5);
await scene.Wait(scene.Seconds(.25));
osc.NoteOff(n);
await scene.Wait(scene.Seconds(1.5)); // long wait between notes
}
console.log(`${id} done`);