Skip to content

Latest commit

 

History

141 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PicoSynth

A polyphonic wavetable synthesizer for the Raspberry Pi Pico 2.

(C) Ray Bellis 2023-2024

NB: this is very much a work in progress!

Current Features

  • 64 voices
  • 16 channel multi-timbral
  • 128 hard-coded presets, a rough General MIDI set
  • 16-bit stereo audio at 48kHz, over either I2S or USB
  • three DCOs per voice — two freely tunable, plus a sub-oscillator
  • the two tunable DCOs each have their own:
    • waveform — sine, square, saw or triangle from a 2048 x 16-bit wavetable, or white noise on the second
    • level
    • coarse tune, in semitones
    • fine tune, in 64ths of a semitone
  • the sub-oscillator is the first DCO read a whole number of octaves down, so it shares that oscillator's waveform and tuning, and has its own level
  • the second DCO has an ADSR amplitude envelope of its own, for breath, a struck partial or a noise transient over a pitched body
  • DCO modulation:
    • LFO
    • ADSR pitch envelope
    • pitch bend
  • resonant state-variable filter (DCF), per voice, with:
    • ADSR envelope, bipolar depth
    • cutoff and resonance from CC 74 and CC 71
    • velocity, key tracking and aftertouch
    • LFO
  • DCA
    • ADSR envelope
    • velocity, channel volume (CC 7) and expression (CC 11)
    • LFO, as tremolo
    • stereo pan
  • LFO, per voice or per channel, with a fade-in and depth from the patch, the mod wheel and aftertouch
  • peak-limited output, stereo linked
  • USB MIDI device
  • Serial MIDI (UART1, pins 4/5)
  • sustain pedal (CC 64), all notes off (CC 123) and all sound off (CC 120)

Audio output

CONFIG_AUDIO_USB in CMakeLists.txt selects the transport:

  • 0 (default) — 16-bit stereo I2S, as configured for the Pimoroni Audio Pack
  • 1 — USB audio. The synth appears to the host as a stereo 48kHz recording device, alongside its MIDI interface, so it can be recorded or monitored over the same cable that carries the notes. No DAC needed

Only one is compiled in.

Hardware

A Raspberry Pi Pico 2 (RP2350) is required — the RP2040 is no longer supported. The audio path uses the M33's FPU and saturating and 64-bit-multiply instructions, none of which exist on the RP2040's M0+.

The RP2350 is overclocked to 250 MHz.

The I2S interface is configured for use with the Pimoroni Audio Pack. A PCB with MIDI DIN ports and I2S DAC is under development.

CONFIG_HW_PICOADK in CMakeLists.txt still selects the pin assignments for the Datanoise PicoADK, but that board is RP2040-based and so will not currently build.

Building

Familiarity with using the Pico SDK is assumed.

My own development system is macOS and I use the arm-none-eabi-gcc compiler v15.2.0 from MacPorts.

Building the code requires only the Pico SDK toolchain and the following repositories:

I use the following in my .cshrc with the above three repositories all checked out into ${PICO_HOME}:

setenv PICO_HOME "/opt/pico"
setenv PICO_SDK_PATH "${PICO_HOME}/pico-sdk"
setenv PICO_EXTRAS_PATH "${PICO_HOME}/pico-extras"

Presets

src/presets.c is generated by utils/gm_presets.py and committed, so building needs nothing but the SDK toolchain. The script lets a patch be written musically — cutoff as a MIDI note, LFO rate in Hz — and converts on the way out. Edit the script rather than the C, then:

python3 utils/gm_presets.py > src/presets.c

Editor setup

utils/clangd_config.py writes a .clangd so that a language server parses the tree the way the cross-compiler does. Without it clangd falls back to the host toolchain and reports errors that are not there. The generated file names one toolchain at one version, so it is not committed — run the script once, and again after changing compiler.

License

This source code is released under the GPLv3.0 License

About

Polyphonic wavetable synthesizer for the Raspberry Pi Pico

Topics

Resources

Stars

66 stars

Watchers

4 watching

Forks

Contributors

Languages