flag
Hz.Pluginsare included withHzWeb. They are built atop the Web Audio Module (WAM) standard and can theoretically be loaded into any WAM host, TOC hereThat said, our focus is providing the necessary batteries required to use HzWeb so we offer no guarantees of their functionality in other WAM hosts.
Hzships with many examples discussed here.right-click for table of contents

Hz.FM7 is a polyphonic 6-operator FM synthesizer based on Google's
music synthesizer for android (msfa) which itself is based
on the Yamaha DX7. We've added support for 33 built-in banks
from a variety of public domain patch sets. We've also
extended it to support stereo out and more voices. Note
that this is the same foundation used by Dexed and a variety
of other online sythesizers. If you need more extensive control
over a DX7 instrument than Bank and Patch, we recommend you explore
online alteratives. Hz.FM7 s a great utility synth that can produce
a wide variety of high-quality synthesized sounds.
To instantiate with preset bank and patch:
let fm7 = await ascene.NewAnode("Hz.FM7", {
name: "myfm7",
preset: {
Bank: 3,
Patch: 5,
Gain: 2.3
}
});

Hz.Samplo is a polyphonic sample-playing instrument. You can initialize
it from a variety of online sample-sets.
Hz.Samplo ships capable of producing literally hundreds of different sounds.
You can also initialize it with your own samples.
Sample-sets come in two categories:
tonal - samples represent notes on an instrument. sound/percussion - samples represent arbitrary sounds that
don't map to musical notes.Hz.Samplo handles both types but your scripts must be aware of this
distinction because it affects the interpretation of MIDI key numbers.
Be aware that some percussion banks organize their sounds based on the
GeneralMIDI standard.
Here is an example instantiation:
let samplo = await scene.NewAnode("Hz.Samplo", {
preset: {
A: 0.1, // soundfonts have a natural attack env.
D: 0.01,
S: 1,
R: 1.5, // user releases prior to end of sbuf.
Gain: 2,
instrument: {
kit: "FatBoy",
inst: "church_organ"
}
}
});

Hz.Osc is a simple polyphonic instrument based on WebAudio's oscillator node.
It has support for Unison voices which is achieved by assigning
multiple (detuned) oscillators to a single note. Hz.Osc implements
a custom note expression, _frequency, that can be useful to
programmatically control an oscillator frequency while a note is held.
This can be thought of as a more general note expression than tuning.
Here is an example instantiation:
let inst = await Anode.New("Hz.Osc", {
preset: {
Waveform: 1,
Gain: .5,
A: .1,
D: .01,
S: 1,
R: .04,
}});

Hz.Genish is a programmable audio processor based on
genish.js which, in turn,
was inspired by gen~ for Max.
The cool thing about genish is that it allows you to develop custom
synths or effects without all the fuss required to produce a full plugin.
Your genish extension/customization is a small JavaScript-let like this:
// a simple FM synth (that plays a single tone)
function FM(g) // g is the genish context with dsp operators.
{
let sineOsc = g.cycle(g.madd(10, g.cycle(4), 440));
return g.mul(sineOsc, .25);
},
To construct:
let mode = "stereo"; // or "mono"
let type = "instrument"; // or "effect"
let genish = await scene.NewAnode("Hz.Genish", {
acfg: {mode, type}
});
await genish.LoadPreset({genish: {
name: "coolsynth",
code: yourFunction.toString(),
wsdir: this.GetCWD()
}};
Examples here: hzplugins/genishTestSynth.j,genishTestEfects.js,genishFM2.js and
genish scriptlets below hzplugins/genish/.
Hz.Genish operators and implementation details are here.

Hz.RetroVocoder is built atop Paul Kellett's 2008 Talkbox plugin.
Its simple interface belies the potential of really cool retro-robot
sounds. You must have two signal sources, typically a voice and and
instrument. These are wired as follows:
scene.Connect(voice, vocoder, 0, 0); // voice goes to vocoder port 0
scene.Connect(inst, vocoder, 0, 1); // instrument goes to vocoder port 1
Vocoder detects the incoming channel counts and reconfigures accordingly, Stereo operation is twice as expensive as mono.
Example here: hzplugins/retrovocder.js

Hz.Noise is a simple synth that produces your choice from three
colors of noise.

Hz.ConvVerb is a simple but powerful reverb built atop WebAudio's convolver.
Hz.ConvVerb implements a filter that applies an impulse-reponse audio file
to the incoming signal. You can use an arbitrary audio sample file (typically
length-constrained) for interesting effects. There are also many online
sources for impulse-response files captured by a range of cheap-to-expensive
tecniques. Make sure to heed their licensing terms!
Here's a snippet from our example: hzplugins/convverb.js.
let rev = await scene.NewAnode("Hz.ConvVerb");
await rev.LoadPreset({Wet: 1, Dry: .2});
// samples CC-BY-SA (C) 2016 Damo
let root = "https://raw.githubusercontent.com/zamaudio/impulses/master";
let ir = `${root}/Hall_mono0.wav`;
await rev.LoadPreset({impulseResponse: ir});

Hz.DynaCompress is a simple wrapper of WebAudio's
DynamicsCompressorNode.
Example here: hzplugins/dynacompress.js.

Hz.Echo is a simple feedback-delay effect with support for PingPong
echo. Included in the feedback path is a lowpass filter. The lower
the FilterCutoff the darker the echo-return.

Hz.Filter implements a SVF filter and provides lowpass, highpass,
bandpass and notch filter options. It also supports resonant frequency
modulation via a built-in LFO. When Keytrack is enabled the
resonant frequency follows the MIDI key events that you provide it.

Hz.Freeverb is a port of the well-known, public-domain Freeverb effect
written by Jezar at Dreampoint, June 2000. Its Freeze parameter
can be employed to add reverb glitch. This alternative to Hz.ConvVerb
supports continuous variation of room-size, etc.
Hz.Genish (above) can also be used to describe custom effects.
Using Hz.Genish as an effect processor requires a couple steps.
First, instantiate the node:
let genish = await scene.NewAnode("Hz.Genish", {
acfg:{type:"effect"}
});
Next, wire an input that produces a sound to be processed, something like:
ascene.Chain(audiosrc, genish, dac);
Next, make sure that your genish scriptlet refers to in1 and/or in2.
These represent your node's left and right input channels. Here's a
simple mono crusher distortion:
function ampcrush(g, ampScale=12)
{
return g.div(g.round(g.mul(g.in1, ampScale)), ampScale);
},
Finally, load your scriptlet.
await genish.LoadPreset({
genish: {
name: "cooleffect",
code: ampcrush.asString(),
wsdir: this.GetCWD()
}
})
More examples here: hzplugins/genishTestEfects.js and
genish scriptlets below hzplugins/genish/;

Hz.LFO is a simple envelope-based Low Frequency Oscillator.
You can design your custom envelopes with
envelope editor and paste
them into your script or the GUI.
For examples see: hzplugins/lfo.js,lfoModulator.js.
// To initialize `Hz.LFO` with a custom envelope:
let lfo = await scene.NewAnode("Hz.LFO", {preset: {
envelope: {
shape: "tooth",
smooth: false,
data: [0, 0, 5, 0.5, 1, -5, 1, 0, 0]
},
}
});
Hz.LFO supports two run modes and this determines how they
should be connected into the audio graph.
// To use `Hz.LFO` as an `amplitude modulator`:
let lfo = await scene.NewAnode("Hz.LFO"); // RunMode:0 is default
scene.Chain(inst, lfo, dac); // inst and dac created elsewhere
// To use `Hz.LFO` as a `parameter modulator`:
let lfo = await scene.NewAnode("Hz.LFO", {preset: {RunMode:1}});
scene.ModulateParam(lfo, inst, "Pan"); // inst created elsewhere
flag Important notes for parameter modulation
- only some anodes have parameters that support parameter modulation.
- make sure that the LFO
OutMinandOutMaxparameters produce a signal range appropriate for the parameter.

Hz.Waveshaper is a simple distortion effect built atop WebAudio's
WaveShaperNode.
Use the combination of InputDrive and Drive parameters
to select your distortion effect. Beside obvious distortion effects,
it is often used to add a warm feeling to a signal. Modulating Drive
is much more expensive than InputDrive since it updates the wave shaping
function.
Here`s an example:
let overdrive = await scene.NewAnode("Hz.Waveshaper",
{preset:{InputGain:2, Drive:1, OutputGain:.5}});
Distortion example here: hzplugins/tuner.js (uses Hz.AudioIn).

Hz.AudioIn connects your computer's default/current input device
into your soundscape or control script. When run, it attempts to
open your computer's audio input device (eg microphone). This
may require you to grant it permission.
warning WARNING if you wire your input directly to
Hz.DACyou may produce nasty feedback. This problem depends on whether your input device can "hear" your speakers.
If you have a USB audio interface it's possible to receive signals from other sources, eg guitar or fancy microphone. Such devices typically have headphone support to address the potential feedback problem.
Hz.AudioIn receives a mono mono signal. If your input device
has multiple channels, the Channel parameter can be specified
during anode construction as follows:
let audioIn = await scene.NewAnode("Hz.AudioIn", {preset:{Channel:1}});
Related nodes: Hz.Tuner, Hz.Recorder, Hz.WebAudioIn.
Examples here: hzplugins/audioin.js, hzplugins/tuner.js.

Most audio scenes include a Hz.DAC node because its the node that
delivers the results of the audio graph to your audio system's
output. For this reason, all roads lead to Hz.DAC.
Hz.DAC is one of the few singletons in the system. There is
no value in creating more than a single instance of it which is
why we provide ascene.GetDAC().

Hz.Blackhole is a utility node that you can use to ensure that
an anode, like Hz.Scope triggers without a connection to Hz.DAC.
It isn't a common requirement but when you need it, you need it.
As with Hz.DAC, Hz.Blackhole is a singleton and therefore
available via ascene.GetBlackhole().
There are no useful outputs of Hz.Blackhole, no use chaining them
to downstream nodes.
See example: hzplugins/blackhole.js.

Hz.Mix is a simple mixing node that provides visual feedback on
the signal levels. It can be configured during instantiation
to either mixdown or preserve the input channels. When mixdown
is enabled, we provide Pan control. This is enabled during construction
like so:
let mix1 = await scene.NewAnode("Hz.Mix", {acfg:{mode:"mixdown"}});
See example: hzplugins/mix.js.

Hz.Scope is used to visualize the audio signal. Usually you use
it as a passthrough anode that intercepts, displays and forwards
the audio signal. It defaults to a stereo configuration but
you can request mono (depicted above) during construction like so:
let scope = await scene.NewAnode("Hz.Scope", {acfg: {mode:"mono"}});
There may be some cases where you don't want to forward the signal.
Unfortunately, unless the scope is ultimately connected to either Hz.DAC
or Hz.Blackhole the scope will not trigger.

Hz.SpectraScope is use to visualize the frequency content of an audio signal.
As with Hz.Scope it must be chained to ultimately arrive at Hz.DAC or
Hz.Blackhole in order to triger. The spectrum is computed from the
combined input channels. Note that both frequency (x) and amplitude (y)
axes are displayed on a logrithmic scale.
See example: hzplugins/spectrascopeTest.js.

Hz.Tuner analyzes the primary pitch of its input signal and works well
for singal with strong tonal content like a guitar. Typically Hz.Tuner
receives mono input from Hz.AudioIn. As with most audio nodes its
output signal must be wired to a downstream node in order to trigger.
See example: hzplugins/tuner.js.

Hz.Recorder records its input signal to a .wav file and deposits
the result below your workspace directory HzWeb/_recordings.
Hz.Recorder supports two operating modes:
Arm, Record, Pause, Disarm/Save to
modify the state of the recorder. When some material has been recorded
and you press Disarm/Save, the .wav file will written. If you forget to
press Record no material will be recorded and no file will be saved.Arm via LoadPreset. You
can specify explicit start and stop times or as shown below your
recordEnd can be "a long time away" and then your script can
explicitly request a stop.// start a recording
await recordNode.LoadPreset({
ctrlMode: "Preset",
prefix: "radio_" + ts,
recordStart: 0,
recordEnd: 1e10, // need to trigger end
});
// later on stop it.
await recordNode.LoadPreset(
{
ctrlMode: "Preset",
disarm: true, // <---- stop recording
recordEnd: ascene.Now(),
});
Interactive example: hzplugins/recorder.js.
Scripted example: algorithmic/radio/radio.js.

Hz.WebAudioIn is the Hz.AudioIn for the internet. You provide
a URL which streams a simple audio signal and it can appear in
your soundscape. Note that we currently support a subset of
potential audio src URLs. Also note that some website URLs
can be offline or become invalid. YMMV.
Here's how to construct:
let mystation = await state.ascene.NewAnode("Hz.WebAudioIn", {
preset: {
Station: name,
URL: url,
Gain: .2,
}});
See example: algorithmic/radio/radio.js.