Skip to content

Instantly share code, notes, and snippets.

@todbot
Last active May 19, 2023 11:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save todbot/b8c48f209fb9917e1ad8d5c84722fb1d to your computer and use it in GitHub Desktop.
Save todbot/b8c48f209fb9917e1ad8d5c84722fb1d to your computer and use it in GitHub Desktop.
Show new synthio.Note API that allows different waveform per Note!
# synthio_note_waveform_demo.py --
# 10 May 2023 - @todbot / Tod Kurt
# Uses cheapie PCM5102 DAC on QTPY RP2040
import time,random
import board, analogio
import audiobusio, audiomixer
import synthio
import ulab.numpy as np
# qtpy rp2040 SPI pins
lck_pin, bck_pin, dat_pin = board.MISO, board.MOSI, board.SCK
SAMPLE_RATE = 28000 # clicks @ 36kHz & 48kHz on rp2040
SAMPLE_SIZE = 256
VOLUME = 12000
wave_saw = np.linspace(VOLUME, -VOLUME, num=SAMPLE_SIZE, dtype=np.int16)
wave_squ = np.concatenate((np.ones(SAMPLE_SIZE//2, dtype=np.int16)*VOLUME,np.ones(SAMPLE_SIZE//2, dtype=np.int16)*-VOLUME))
wave_sin = np.array(np.sin(np.linspace(0, 4*np.pi, SAMPLE_SIZE, endpoint=False)) * VOLUME, dtype=np.int16)
waveforms = (wave_saw, wave_squ, wave_sin)
amp_env = synthio.Envelope(attack_time=0.3, decay_time = 0.05, release_time=2.4,
attack_level=1, sustain_level=1.0)
synth = synthio.Synthesizer(sample_rate=SAMPLE_RATE)
audio = audiobusio.I2SOut(bit_clock=bck_pin, word_select=lck_pin, data=dat_pin)
mixer = audiomixer.Mixer(voice_count=1, sample_rate=SAMPLE_RATE, channel_count=1,
bits_per_sample=16, samples_signed=True, buffer_size=2048 ) # buffer_size=4096 )
audio.play(mixer)
mixer.voice[0].play(synth)
notes = [45, 57, 52]
last_note_time = 0
note_i=0
wave_i=0
waveform = waveforms[wave_i]
while True:
if time.monotonic() - last_note_time > 1.0:
last_note_time = time.monotonic()
n = notes[note_i]
freq = synthio.midi_to_hz(n)
vibrato_rate = time.monotonic() / 1000
note = synthio.Note( frequency=freq, envelope=amp_env,
waveform=waveform,
vibrato_depth=0.1, vibrato_rate=5 )
synth.release_all_then_press( (note,) )
note_i = (note_i+1) % len(notes)
if note_i==0:
wave_i = (wave_i + 1) % len(waveforms)
waveform = waveforms[wave_i] # change waveform
@todbot
Copy link
Author

todbot commented May 11, 2023

and this code sounds like:

synthio_note_waveform_demo.mp4

@IrregularShed
Copy link

As a heads-up, vibrato_depth and vibrato_rate have become tremolo_depth and tremolo_rate in the 8.1.0-rc.0 build (this may have been the case with beta 2 as well). I've got this running at the moment on a Seeed XIAO RP2040 with a cheap DAC and I could leave it running all day quite happily, it sounds lovely!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment