Wavetable synthesis is perhaps the oldest technique for creating sounds with computers. It involves the storage of a single period of a periodic waveform in a circular buffer. By varying the ``speed'' with which a read pointer is advanced through the buffer, one can achieve output waveforms of different frequencies. This technique is distinct from simple PCM sample playback in that it always implies looping over the buffer (rather than a ``read once'' behavior).
Wavetables typically consist of between 128 - 2048 table values (powers of two are common).
The ``pitch'' of the sound that is produced with wavetable synthesis is dependent on the table size, frequency content of the table data, and playback rate.
A table pointer (or phase accumulator) is incremented at a variable rate to produce sounds at different frequencies.
For a table length of N samples, a sample rate of fs samples per second, and a phase increment p = 1 sample per time step, the output signal will have a fundamental frequency of fs / N (assuming the wavetable holds only one period of the waveform).
The phase increment necessary to produce an output signal with fundamental frequency f is given by p = N f Ts, where Ts is the sample period.
One of the most common uses of wavetable synthesis is to produce sinusoidal signals. In this case, the wavetable holds one period of a sinusoid, as shown in Fig. 1 below.
A sinusoidal wave table.
The sinusoidal oscillator frequency is controlled by the phase increment as described above.
An arbitrary phase offset can be implemented by an initial pointer offset into the wavetable. For example, a phase offset of pi/4 radians would correspond to a phase increment of 16 samples when the table length is 64 samples.
Because the wavetable technique implies a circular buffer, output signals are inherently periodic (assuming a relatively constant phase increment).
More complex periodic signals can be generated with wavetable synthesis by computing a waveform using additive synthesis. For example, we could easily add a weighted sinusoid to the table shown in Fig. 1 that completes 2 cycles in 64 samples (or other higher integer multiples).
When making use of wavetables with more complex frequency content, one must be careful when adjusting the phase increment to avoid aliasing.
In most cases, the phase increment necessary to produce a specified output frequency is not an integer value.
When this happens, we have several options for determining appropriate phase and/or ouput values, including truncation, rounding, and interpolation.
If a given phase (or table index) value at a certain instant was 56.7, for example, the truncation approach would choose the table value at index 56. The rounding approach would choose the table value at index 57.
Interpolation involves computing the table output at a fractional index in terms of a weighted combination of table values in the vicinity of that index. Several interpolation methods are common, including linear interpolation and the use of cubic splines.
The method used to determine the wavetable output can have significant affect on the quality of the resulting signal, as demonstrated in Figs. 2 and 3.
The magnitude spectrum of a rounding wavetable sinusoidal oscillator implementation.
The magnitude spectrum of a linearly-interpolating wavetable sinusoidal oscillator implementation.
As seen in the figures above, linear interpolation provides significant improvement in quality over rounding..
Another important factor in wavetable synthesis quality is the size of the table data. In general, larger tables provide more accurate results.
Synthesis approaches using multiple wavetables are also common.
For example, if one wants to vary the evolution of a tone over time, multiple tables can be used that are mixed into the result over time. In this case, no more than two tables are used at any given time and the mix is controlled by envelopes as shown in Fig. 4.
The MSP cycle~ object implements wavetable synthesis with a table size of 512 samples. By default, cycle~ produces a sinusoidal output though it can be linked to a buffer~ object for arbitrary table data.
The MSP wave~ object implements wavetable synthesis for variable length wavetables. The data used by the wave~ object is stored in a buffer~ object.
The MSP groove~ object implements variable rate looping wavetable playback. Again, the data used by the groove~ object is stored in a buffer~ object.
In the Synthesis ToolKit (STK), the SineWave class provides a sinusoidal oscillator wavetable implementation using a default table size of 2048 samples.
The WaveLoop class provides looping functionality for any standard audio file format (WAV, SND, AIFF, MAT-file) of arbitrary size and number of channels.