Wavetable Viewer
Wavetable Viewer lets you visualize and listen to wavetables stored in WAV files. It will automatically reload the wavetable as it gets modified, speeding up your process of creating wavetables.
Wavetable Coding Tutorial
Here’s a sawtooth wavetable created in Python:
# main.py
import numpy as np
from scipy.io.wavfile import write
FRAME_SIZE = 2048
frame = np.linspace(-1, 1, FRAME_SIZE)
write("output.wav", 44100, frame.astype(np.float32))
We can run it like this:
python3 -m venv .venv
source ./venv/bin/activate
pip install numpy scipy
python main.py
We can preview the wavetable using Wavetable Viewer:
wtv ./output.wav &
The & starts the program in the background, so we can keep using our shell.
We can now start modifying the script. Let’s turn the saw wave into a square wave:
x = np.linspace(-1, 1, FRAME_SIZE)
frame = np.sign(x)
Running the script will overwrite output.wav, and Wavetable Viewer will automatically reload it
and show you the new wavetable.
We can try a few more waveforms:
frame = np.sign(x - 0.5)
frame = np.abs(x)
frame = x ** 2
We set endpoint=False for the sine wave, since it is a periodic function, and we don’t want to
have duplicate values at the start and end of a waveform.
x = np.linspace(-1, 1, FRAME_SIZE, endpoint=False)
frame = np.sin(x * 2 * np.pi)
Here’s an example of creating a sequence of frames that interpolate between two waveforms:
FRAMES = 256
x = np.linspace(-1, 1, FRAME_SIZE, endpoint=False)
sine = np.sin(x * np.pi)
square = np.sign(x)
wt = np.empty((0))
for frame_id in range(0, FRAMES):
t = frame_id / (FRAMES - 1)
frame = t * square + (1 - t) * sine
wt = np.concatenate((wt, frame))
write("output.wav", 44100, wt.astype(np.float32))
Here’s an example for creating wavetables using the Fourier Series:
wt = np.zeros(FRAME_SIZE)
x = np.linspace(-1, 1, FRAME_SIZE, endpoint=False)
for h in range(1, FRAME_SIZE):
wt += np.sin(x * np.pi * h) * (1 / (h * np.pi))
We can go many ways from here. Have fun!