TL;DR: I made a small LFO-driven drone synth. Go and play with it.
Here's a little audio experiment that I've been wanting to try for quite a while. The idea is to run several infinitely sustained instruments, also known as drones, and modulate them with low-frequency oscillators, making their parameters evolve over time.
The twist is that the LFOs use only basic, stock waveforms (sine, square, saw and triangle), but every parameter is modulable, including the LFO parameters themselves. This infinitely chainable architecture generates complex wave patterns that can make the drone evolve autonomously for a potentially very long time (especially if the oscillator frequencies are relatively prime to one another).
It's also a way to showcase my new static site generator, which can serve islands of lazy-loaded dynamic mini-apps in the middle of static Markdown.
Web Audio is made for this
It turns out this is extremely easy to do with Web Audio. Any AudioNode can be connect()ed to a parameter of another AudioNode, which means that any Oscillator node doubles as an LFO source if its frequency is low enough and it's connected to a parameter of another oscillator (if its frequency is high, you get FM synthesis, but that's another story).
This mechanism is very flexible and it's almost always used for internal machinery in synths. Here, we expose it to the user and use it to control a little endless music machine.
Oscillating oscillators
To understand how it works, here's a small visual demo that shows how chaining two LFOs to a wave generator creates a complex signal.
The leftmost LFO is connected to the rate parameter of the middle LFO, which in turn is connected to the frequency parameter of an instrument (a simple wave generator with a capped frequency, to make it easier to animate).
When LFO 1 has a low frequency, LFO 2's frequency moves up and down slowly around its base frequency. If you look at the charts in the second half of the demo (the solid line shows the parameter automation, the dashed line shows the resulting output signal) or the small moving pips on the parameter sliders, you can see how LFO 1 drives LFO 2's rate, while LFO 2's signal drives the oscillator's frequency parameter.
Connected this way, the two modulations compose: the result is a hierarchy of changes, with LFO 1 creating a second-order change and LFO 2 a first-order (direct) change to the instrument's parameter.
Press "Animate" and play with the parameter sliders or the signal selector; you will see how the three nodes influence one another along the chain in real time.
Chained LFO modulation
LFO 1 changes LFO 2's rate, and LFO 2 changes the oscillator's rate. Enable JavaScript to animate the linked curves.
The synth
So here's the instrument. Some instructions:
- Press play to hear it.
- There are three types of nodes: instruments, oscillators and filters.
- Instruments and filters output audio signals: they can be connected to the Master (audio out) node or to other filters.
- Oscillators output control signals: they can be connected to any parameter input.
- Oscillators have two output ports with opposite polarities, which is useful if you want your oscillator to decrease one parameter when it increases another.
- Drag and drop a node's output port onto another node's input port to create a connection. Click on an existing connection to select it, and press Delete to remove it. There are a bunch of presets that you can select and run.
- You can mute an instrument, or zero an LFO, by pressing its "bypass" button.
- You can't save the current state of the synth, but the whole state is reflected in the URL in real time, so you can bookmark your creation or copy its URL and paste it somewhere, like this. Have fun.