We are going to take you through the basics of wavetable synthesis theory and use that knowledge to create a real-time synthesiser in Python. At the moment, it is controlled by the computer keyboard, but it could easily be adapted to accept a MIDI keyboard as input.
The Python implementation of such a synthesiser turns out to be too slow for polyphonic sound (ie playing multiple notes at the same time) so we’ll use Cython, which compiles Python to C so that you can then compile it to native machine code to improve the performance. The end result is polyphony of three notes, so this is not intended for use as a serious synthesiser. Instead, this tutorial will enable you to become familiar with synthesis concepts in a comfortable language: Python.
Once you’re finished, try taking this project further by customising the mapping to better fit your keyboard layout, or tweaking the code to read input from a MIDI keyboard.
1. Install packages
Using the latest Raspbian image, install the required packages with the following commands:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python-pip python2.7-dev portaudio19-dev
sudo pip install cython pyaudio
The final step compiles Cython and PyAudio from source, so you might want to go and do something else while it works its magic.
2. Disable built-in sound card
We had issues getting the Raspberry Pi’s built-in sound card to work reliably while developing the synthesis code. For that reason, we are using a USB sound card and will disable the built-in card so that the default card is the USB one:
sudo rm /etc/modprobe.d/alsa*
sudo editor /etc/modules
Change ‘snd-bcm2835’ to ‘#snd-bcm2835’ and save, then:
sudo reboot
3. Test sound card
Now we can test the USB sound card. Type alsamixer and then ensure that the volume is set to a comfortable level. If you’re plugging speakers in, you’ll probably want it set to 100%. Then type speaker-test, which will generate some pink noise on the speakers. Press Ctrl+C to exit once you are happy that it’s working.

4. Start project
Start by creating a directory for the project. Then download one cycle of a square wave that we will use as a wavetable, like so:
mkdir synth
cd synth
wget liamfraser.co.uk/lud/synth/square.wav
5. Create compilation script
We need a script that will profile our Python code (resulting in synth.html). Generate a Cython code for it and finally compile the Cython code to a binary with GCC:
editor compile.sh:
#!/bin/bash
cython -a synth.pyx
cython –embed synth.pyx
gcc -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -O3 -I /usr/include/python2.7 -o synth.bin synth.c -lpython2.7 -lpthread
(Notice the options that tell the compiler to use the floating point unit.) Make it executable with:
chmod +x compile.sh
6. Start to code
Our code file is going to be called synth.pyx. This extension tells Cython that it is not plain Python code (and as such, can’t be ran in a normal Python interpreter). Create the file with your favourite editor and add the imports.
7. MIDI Table
To synthesise the standard note of a piano, we need a table of MIDI values. MIDI notes range from 0-127. MIDI note 60 is middle C on a piano. The MIDI Table class has a ‘get note’ function that returns the frequency of a note when you give it a MIDI note number.

Full Code for step 7
class MIDITable:
# Generation code from
# http://www.adambuckley.net/software/beep.c
def __init__(self):
self.notes = []
self.fill_notes()
def fill_notes(self):
# Frequency of MIDI note 0 in Hz
frequency = 8.175799
# Ratio: 2 to the power 1/12
ratio = 1.0594631
for i in range(0, 128):
self.notes.append(frequency)
frequency = frequency * ratio
def get_note(self, n):
return self.notes[n]
—
Continue this project with part two, which will be available from the 6th of February on linuxuser.co.uk