Version: 0.3 - 21 Apr 2025
Welcome to a CircuitPython Synthio Tutorial.
In CircuitPython, synthio is a built-in module for doing sound synthesis
on microcontrollers such as the Pico (RP2040/RP2350) and ESP32.
This guide will focus on a Pico RP2040 and PCM5102a I2S DAC,
but it applies to any board that supports synthio.
The repo for this tutorial lives at https://github.com/todbot/CircuitPython_Synthio_Tutorial where you can download all the code as a zip file.
This tutorial assumes you know some Python and CircuitPython already.
It doesn't try to assume you know much about synthesizers or music theory,
but of course, knowing the basics of "subtractive synthesis" will help understand
how synthio works and how it differs from that standard.
This guide hopes to show how synthio "thinks" about sound synthesis,
show techniques for implementing common synthesis concepts with synthio,
and provide useful code snippets to help make new synth things in CircuitPython.
This guide is broken up into multiple sections. Each section focuses on a topic, and will use techniques and terms discussed in previous sections.
Every example code block is a fully working program, no code snippets here, with
download links to ready-to-run code.
Some functionality will be provided by external libraries or an included script
(most notably synth_setup.py).
Each example code block also exists as a code_[name].py file that can be copied to
your device's CIRCUITPY drive as code.py to run. The file will sometimes
contain extra explanatory comments or print statements that will be elided
in this guide.
Each example (with a few exceptions) will do something sonically interesting by itself, but also have a bit of interactivity with the knobs and button. So even if you don't have the knobs & button wired up, you should still get a sense of what the example is about.
-- Going from a fresh Pico to making boops and responding to inputs
-- Making those boops sound more alive with LFOs and Envelopes
-- How to use synthio's filters and modulate them
-- Change a note's waveform, at any time, even use WAVs
-- How to respond to MIDI messages (velocity, pitchbend, CCs) in synthio
-- Using the audiofilters and audiodelays modules to add effects
-- Buildling a full synth voice in synthio
Here's some simple examples using synthio showing what's possible
- tiny_lfo_song -- song with just LFOs
- eighties_dystopia -- 80s-style miasma
- quicky_theremin -- simple theremin using
touchio - wavetable_midisynth -- Play wavetables with MIDI
- monosynth1 -- MIDI-controlled thick monosynth
- two_pot_drone_synth -- 3-voice two-knob drone synth
I and others have created several projects and libraries that use synthio.
Some are listed here:
- todbot: circuitpython-syntho-tricks
- todbot: pico_test_synth
- todbot: qtpy_synth
- todbot: Workshop Computer
- gamblor: synth drum sounds
- cedargrove CircuitPython_WaveBuilder
- cedargrove: CircuitPython_Chime
- relic-se: PicoSynth_Sandbox
- relic-se: CircuitPython_SynthVoice, CircuitPython_Waveform, CircuitPython_KeyManager
- 0.3 - 21 Apr 2025 - added video examples for Section 3
- 0.2 - 14 Apr 2025 - added video examples for Section 1 & 2
- 0.1 - 4 Apr 2025 - initial release for review