Skip to main content

Sound Design with Vital's Spread Knobs

Another Bunting tutorial video has dropped, titled "I HAD NO IDEA VITAL COULD DO THIS." It is recommended viewing, but not necessary for comprehension of this blog post.

Vital, for the uninformed, is a free and open source VST plugin for variable wavetable synthesis, where wavetables have two dimensions. One dimension is time and the other is table position, which allows scrubbing through a variety of timbres. Vital stands out among Serum and Massive for its support for "spectral warping," a feature that isn't really explained but sounds great.

By exploring advanced features of Vital, Bunting found a workflow which can be briefly summarized as follows:

  1. Set the variable wavetable to "Harmonic Series." Modulation of table position produces sine waves for the first 16 harmonics with crossfading between consecutive harmonics.

  2. Use 16 copies of the oscillator, themselves tuned to a harmonic series.

  3. Let X is a global signal ranging from 0 to 1. For each oscillator with index N (0-indexed), set its table position to X * N / 15.

  4. Distribute the oscillators across the stereo field.

The signal X is roughly equivalent to the "table spread" knob in Vital. It is one of three spread knobs available -- the other two are "spectral spread" and "distortion spread." We'll get to those in a moment.

Reimplementation in SuperCollider is entirely possible, although making a crossfading harmonic series is a little tricky:

(
{
    var snd, n, harmonics, freq, oscillatorRatios, tableRatio, phase, initialPhases;
    freq = 36.midicps;
    harmonics = 16;
    n = 16;
    oscillatorRatios = (1..n);
    tableRatio = LFSaw.ar(1/3, 1).range(0, 1) * (0..harmonics - 1) + 1;
    initialPhases = { Rand(0, 2pi) } ! oscillatorRatios.size;
    phase = (Phasor.ar(0, 2pi * freq / SampleRate.ir, 0, 2pi) + initialPhases) % 2pi;
    snd = SinOsc.ar(0, (phase * tableRatio.floor * oscillatorRatios) % 2pi).blend(
        SinOsc.ar(0, (phase * (tableRatio.floor + 1) * oscillatorRatios) % 2pi
    ), tableRatio.frac);
    snd.sum ! 2 * -25.dbamp;
}.play(fadeTime: 0);
)

[audio]

I couldn't get my spread implementation to sound exactly like Vital, so it's possible I've done something wrong. Either way, it sounds fresh and exciting. Already we have access to interesting variations, including using odd harmonics instead of all harmonics:

[audio]

Or modulating the number of active oscillators:

[audio]

Spectral warp and distortion

As mentioned before, Vital also has "spectral spread" and "distortion spread" knobs. To understand these, we must first describe the "spectral warp" and "distortion" knobs. It is easier to describe the distortion settings first as most of them are fairly intuitive. Some digging in the Vital source code gave me the following:

  • Sync enables oscillator hard sync. The fundamental frequency (sync frequency) is given by MIDI input, while the ratio of the intrinsic frequency to the sync frequency is controlled by the knob.

  • Formant is identical to Sync, but the waveform is multiplied by a half-sine window for a smoother sound.

  • Quantize performs sample rate reduction on the phase of the oscillator, with the chunkiness of the quantization controlled by the knob.

  • Bend stretches the phase of the waveform with a nonlinear formula: \(x^3 + (3d + f)(x^2 - x^3) + (3d - f)(x - x^2 + x^3)\) where \(x\) is phase from 0 to 1, \(d\) is the distortion knob from 0 to 1, and \(f = 2d - 2d^2\).

Not all of these sound interesting in the context of the spread knobs.