Hz.Osc
has an optional phase modulation (audio) port. We can
connect one instance to another to get gnarly sounds.
First we connect two Hz.Osc
nodes.
let pm = scene.NewAnode("Hz.Osc", {name:"PM"});
let inst = scene.NewAnode("Hz.Osc", {name:"Inst", cfg:"stereo"});
let dac = scene.GetDAC();
scene.Chain(pm, inst, dac);
Note that our phase-modulating oscillator is a mono (default) configuration, while our instrument is stereo.
Next we set up some default parameters and present the Webview GUI.
// set up our phase modulator
const sq = pm.GetParamValueForMenuItem("Waveform", "SquareTab");
pm.SetParam("Waveform", sq);
// configure the instrument oscillator
inst.SetParam("Waveform", 0);
inst.SetParam("PMScale", 2); // the amount of the PM effect.
inst.SetParam("/adsr/R", .05);
await scene.Sync();
// We raise the webview interfaces via hzplugins tab.
// There you can manually adjust the PM Amplitude (and other params) for
// dramatic affect. Since Hz.Scope is active you can explore how
// the phase modulation affects the signal spectrum.
inst.Show();
pm.Show();
await scene.Wait(0); // make sure scene.Now is up-to-date.
Finally, we play some notes and progrmatically modify the PM frequency
via its Transpose
parameter.
let durS = .25;
let dur = scene.Seconds(durS);
let when = scene.Now() + dur;
for(j=0;j<10;j++)
{
// modify the frequency of the modulator relative to the current key.
pm.SetParam("Transpose", 2*(j-5));
for(let i=0;i<15;i++)
{
let key = 50 + i;
pm.Note(key, .9, dur, when);
inst.Note(key, .9, dur, when);
when += 1.3*dur;
await scene.Wait(dur);
yield;
}
}