Created
April 24, 2025 21:15
-
-
Save gamblor21/e0a31217ec6dc8be68048e790f29ccb4 to your computer and use it in GitHub Desktop.
USB Midi to CircuitPython synthio with audio effects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import board | |
import busio | |
import adafruit_midi | |
import usb_midi | |
import audiobusio, audiocore, audiomixer, audiodelays, audiofilters, synthio, audiofreeverb | |
from waveforms import waveforms | |
from adafruit_midi.control_change import ControlChange | |
from adafruit_midi.note_off import NoteOff | |
from adafruit_midi.note_on import NoteOn | |
time.sleep(1.0) | |
CHANNELS=2 | |
SRATE=44100 | |
import ulab.numpy as np | |
SAMPLE_SIZE = 512 | |
SAMPLE_VOLUME = 14000 # 0-32767 | |
wave_sine = np.array(np.sin(np.linspace(0, 2*np.pi, SAMPLE_SIZE, endpoint=False)) * SAMPLE_VOLUME, dtype=np.int16) | |
i2s_bclk, i2s_lclk, i2s_data = board.GP20, board.GP21, board.GP22 | |
audio = audiobusio.I2SOut(bit_clock=i2s_bclk, word_select=i2s_lclk, data=i2s_data) | |
mixer = audiomixer.Mixer(voice_count=1, channel_count=CHANNELS, sample_rate=SRATE, buffer_size=2048) | |
audio.play(mixer) | |
current_wave = 0 | |
SAMPLE_SIZE = len(waveforms[0]) | |
wavetable = np.zeros(SAMPLE_SIZE, dtype=np.int16) # intially all zeros (silence) | |
wavetable[:] = waveforms[current_wave] | |
synth = synthio.Synthesizer(channel_count=CHANNELS, sample_rate=SRATE)#, waveform=wavetable) | |
#chorus = audiodelays.Chorus(max_delay_ms=50, delay_ms=2, voices=1, buffer_size=1024, channel_count=CHANNELS, sample_rate=SRATE) | |
chorus = audiofreeverb.Freeverb(roomsize=0.75, damp=0.5, mix=0.4, channel_count=CHANNELS, sample_rate=SRATE) | |
chorus.play(synth) | |
#lpf = audiofilters.Filter(channel_count=CHANNELS, sample_rate=SRATE, mix=1.0) | |
#lpf.filter= synth.low_pass_filter(frequency=10000, Q=1.0) | |
#lpf.play(chorus) | |
#mixer.voice[0].play(lpf) | |
mixer.voice[0].play(chorus) | |
### MIDI SETUP | |
midi = adafruit_midi.MIDI(usb_midi.ports[0]) | |
notes = {} | |
def PlayNote(msg): | |
print("Playing ", msg) | |
amplitude = msg.velocity/127.0 / 2 | |
if msg.note not in notes: | |
note = synthio.Note(synthio.midi_to_hz(msg.note), amplitude=amplitude) | |
notes[msg.note] = note | |
synth.press(note) | |
def StopNote(msg): | |
print("Stopping ", msg) | |
note = notes.pop(msg.note, None) | |
if (note is not None): | |
synth.release(note) | |
def CC(msg): | |
global wavetable, current_wave | |
print("CC ", msg) | |
if (msg.control == 70): | |
if msg.value==1: | |
chorus.delay_ms += 0.2 | |
else: | |
if chorus.delay_ms >= 0.2: | |
chorus.delay_ms -= 0.2 | |
print(chorus.delay_ms) | |
if (msg.control == 71): | |
if msg.value==1: | |
chorus.voices += 1 | |
else: | |
if chorus.voices > 1: | |
chorus.voices -= 1 | |
print(chorus.voices) | |
if (msg.control == 72): | |
if msg.value==1: | |
if chorus.mix <= 1.0: | |
chorus.mix += 0.05 | |
else: | |
if chorus.mix > 0.0: | |
chorus.mix -= 0.05 | |
print(chorus.mix) | |
if (msg.control == 74): | |
if msg.value==1: | |
current_wave += 1 | |
if (current_wave >= len(waveforms)): | |
current_wave = 0 | |
else: | |
current_wave -= 1 | |
if (current_wave == -1): | |
current_wave = len(waveforms)-1 | |
wavetable[:] = waveforms[current_wave] | |
print(current_wave) | |
def CC_reverb(msg): | |
global wavetable, current_wave | |
print("CC ", msg) | |
if (msg.control == 70): | |
if msg.value==1: | |
if chorus.roomsize < 1.0: | |
chorus.roomsize += 0.05 | |
else: | |
if chorus.roomsize >= 0.05: | |
chorus.roomsize -= 0.05 | |
print(chorus.roomsize) | |
if (msg.control == 71): | |
if msg.value==1: | |
if chorus.damp < 1.0: | |
chorus.damp += 0.05 | |
else: | |
if chorus.damp >= 0.05: | |
chorus.damp -= 0.05 | |
print(chorus.damp) | |
if (msg.control == 72): | |
if msg.value==1: | |
if chorus.mix < 1.0: | |
chorus.mix += 0.05 | |
else: | |
if chorus.mix > 0.0: | |
chorus.mix -= 0.05 | |
print(chorus.mix) | |
if (msg.control == 74): | |
if msg.value==1: | |
current_wave += 1 | |
if (current_wave >= len(waveforms)): | |
current_wave = 0 | |
else: | |
current_wave -= 1 | |
if (current_wave == -1): | |
current_wave = len(waveforms)-1 | |
wavetable[:] = waveforms[current_wave] | |
print(current_wave) | |
while True: | |
time.sleep(0.01) | |
msg = midi.receive() | |
if isinstance(msg, NoteOn): | |
PlayNote(msg) | |
if isinstance(msg, NoteOff): | |
StopNote(msg) | |
if isinstance(msg, ControlChange): | |
if isinstance(chorus, audiofreeverb.Freeverb): | |
CC_reverb(msg) | |
else: | |
CC(msg) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment