Goal: build the third synthesis mode, the wavetable oscillator, which reads its tone from a stored single-cycle waveform and morphs between many such shapes. Done: a WavetableOscillator sits on the same Oscillator base as Weeks 2 and 3 and reads 2048-sample frames from a set of tables. A position control morphs across up to sixty-four frames, the series is band-limited by precomputed mip levels so it does not alias, and the read between stored samples is either linear or cubic. The tables themselves are captured from the plugin's own oscillators and modules. The evidence below is rendered straight from that oscillator.
The shared base, a third time
Weeks 2 and 3 built two synthesis modes on one shared Oscillator base, each inheriting the phase accumulator and note handling and supplying only its own processSample. The wavetable mode is the third subclass and follows the same pattern: the WavetableOscillator takes the base unchanged and fills in one method to turn the current phase into a sample.
The three modes now reach a tone by three different routes. The subtractive oscillator generates one harmonically rich shape and band-limits it as it goes. The AdditiveOscillator starts from silence and sums sine partials. The wavetable oscillator does neither: it reads a shape that was computed and stored ahead of time. That makes it the cheapest of the three per sample and the most open ended in character, since a stored shape can be anything, not only what a live formula produces.
Tables, frames, and morphing
A wavetable is a named set of frames. Each frame is one single-cycle waveform, 2048 samples long, holding exactly one period of a tone. A built-in table carries sixty-four frames, ordered so that neighbours are similar and the set as a whole moves from one character to another across its length.
The position control places a read point along that ordered set, from the first frame to the last. The oscillator reads the two frames nearest the read point and blends between them, so moving position morphs the tone smoothly from one stored shape into the next rather than switching between them. Where the additive oscillator computes its whole spectrum every sample, the wavetable reads a precomputed cycle and interpolates, which is the trade the mode makes: less to calculate in real time, and a character fixed at the moment the table was built.
Where the tables come from
The nine selectable built-in tables are not drawn by hand. Each is captured from real signal processing already in the plugin, so the wavetable mode inherits the character of the other modes rather than approximating it. The Basic Analog table is captured cycle by cycle from Week 2's virtual-analog SubtractiveOscillator, its frames moving from saw to square to triangle to sine. The PWM table is that same oscillator's square at narrowing pulse widths. The Wavefolded table is a triangle driven through the project's Buchla-style wavefolder at rising depth.
Others are built from data rather than captured. The Formant table sums harmonics weighted by measured vowel formant frequencies (Hillenbrand et al. 1995), so sweeping position moves through the vowels. The rest cover a harmonic sweep, two-operator FM, bandpass-filtered noise, and bit-reduced digital shapes. A ninth table, Shape Morph, was added after this week and transitions between the eight earlier tables, producing a meta-morph across the whole library. Beyond the built-ins, the oscillator loads user tables from .wav files: any file whose length is a whole number of 2048-sample frames is accepted into one of twenty-four further slots, and its frames are band-limited on load the same way the built-ins are.
Mip levels and band-limiting
A stored cycle has a fixed set of harmonics. Play it back at a high pitch and the upper harmonics cross the Nyquist frequency and alias, the same problem the first two modes had to solve. The wavetable answers it the way image scaling does, with a mipmap. When a table is built, each frame is run through an FFT and stored not once but as a dozen progressively band-limited copies, each mip level keeping half as many harmonics as the one below it.
At playback the oscillator chooses the mip level from the pitch: the higher the note, the more heavily band-limited the copy it reads, and it blends between two adjacent levels so the brightness does not step as the pitch climbs. A high note therefore reads a copy whose aliasing harmonics were already removed when the table was built, and the tone does not fold. This is the third mode and the third answer to one problem. The subtractive oscillator band-limits its shape as it generates it; the additive oscillator declines to sum a partial above Nyquist; the wavetable oscillator precomputes band-limited copies and picks one to fit the note.
Interpolation and frequency modulation
The read point rarely lands exactly on one of the 2048 stored samples, so the oscillator interpolates between them. The default is linear, a straight line between the two nearest samples. A cubic option instead reads four samples and fits a curve through them, which follows a steep part of a waveform more closely at a little more cost per sample. Linear is enough for the smoother tables; cubic earns its cost on the bright ones.
A separate frequency-modulation input lets another source repitch the oscillator sample by sample. The input is added to the oscillator's own frequency and clamped below Nyquist before it advances the phase. Nothing drove that input at the time of this week. It is now fed by an FM Depth control on each oscillator slot, added in a later pass, which lets one oscillator bend the pitch of another at four times the host rate.
Position and phase jitter
Like the additive partials, the wavetable read is never held perfectly still. Two small, always-on wanders sit on it: a jitter in the read position, so the morph point drifts a little, and a smaller one in phase. Both are refreshed once per cycle and slewed toward their new values over a few milliseconds rather than jumped, because a sudden change at the cycle boundary is itself a click source.
The motion is seeded per voice, so eight voices playing the same table do not move in lockstep. It is the same principle as the noise seeding in Week 2 and the partial drift in Week 3: the exact stored waveform is the starting point, not the finished sound. As with the additive mode, the read begins aligned at note-on and the opening of a note is a known area still being refined, not a settled result.
Evidence
The assets below are rendered headless from the plugin's own wavetable oscillator (one voice, no analogue coloration, 48 kHz), so they show the real code path. They use the Basic Analog table, whose frames morph from a saw through a square and a triangle to a sine. These are the shapes captured from Week 2's virtual-analog oscillator, band-limited and stored. The waveforms and the spectrum below are drawn from the rendered audio, not from the table formula.
position settings on the Basic Analog table, one stored cycle each, rendered from the oscillator. As position advances (down the panels) the read point moves across the frames and the stored shape morphs from a saw through a square and a triangle to a sine. Each shape is band-limited: the small notches at the triangle's corners are the slope-change corrections from Week 2, not glitches. Sweeping position in play moves continuously between these shapes rather than in steps.
position control swept slowly across the Basic Analog table on one held note, from the saw through the square and triangle to the sine and back, the morph heard as a continuous change rather than a set of steps. Note: this file measures +1.16 dBFS true peak from MP3 codec inter-sample reconstruction; sample-level peak is 0 dBFS and no hard clipping is present (flat factor 0.000000).Reflection
Reading a stored cycle is close to a plain table lookup, and the lookup was the quick part. The work, and the week's real surprise, was in the band-limiting. Each stored cycle is turned into a dozen progressively band-limited copies through a Fourier transform, and a small error in how the samples were packed into that transform quietly dropped the second half of every cycle. The tables still made sound, and their spectra looked plausible, so the oscillator seemed to work while the stored shapes were malformed underneath. It only showed plainly when I rendered a saw and watched it sit at silence for half of every period. Fixing it meant not trusting that a reasonable-looking spectrum meant a correct waveform, and going back to the shapes themselves. With the packing corrected the tables read as a clean saw, square, triangle, and sine, the evidence above. The lesson was the one this whole project keeps teaching: measure the thing you actually care about, not the thing that is easy to look at.
References
- Robert Bristow-Johnson. Wavetable Synthesis 101, A Fundamental Perspective, 101st AES Convention, preprint 4400, 1996 (wavetable oscillators, band-limited tables, and their equivalence to additive synthesis).
- Julius O. Smith III. Physical Audio Signal Processing, W3K Publishing, 2010 (band-limited interpolation and table lookup).
- James Hillenbrand, Laura A. Getty, Michael J. Clark and Kimberlee Wheeler. Acoustic characteristics of American English vowels, Journal of the Acoustical Society of America 97(5), 1995. The measured formant data behind the Formant table is available as an open dataset, hosted with the authors' permission.