Skip to content

Commit dd9a1dc

Browse files
authored
Merge pull request #3193 from adafruit/bass_synth
adding bass synth code
2 parents 40e5d08 + 89e1d72 commit dd9a1dc

1 file changed

Lines changed: 101 additions & 0 deletions

File tree

MIDI_Bass_Synth_Stomp_Box/code.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# SPDX-FileCopyrightText: 2026 Liz Clark for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
"""Bass Synth MIDI Stomp Box"""
5+
6+
import board
7+
import busio
8+
import adafruit_midi
9+
import keypad
10+
from digitalio import DigitalInOut, Direction
11+
# pylint: disable=unused-import
12+
from adafruit_midi.control_change import ControlChange
13+
from adafruit_midi.pitch_bend import PitchBend
14+
from adafruit_midi.note_off import NoteOff
15+
from adafruit_midi.note_on import NoteOn
16+
from adafruit_midi.program_change import ProgramChange
17+
from adafruit_ticks import ticks_ms, ticks_add, ticks_diff
18+
19+
# status LED
20+
led = DigitalInOut(board.GP18)
21+
led.direction = Direction.OUTPUT
22+
led.value = True
23+
24+
# UART MIDI
25+
uart = busio.UART(board.GP0, board.GP1, baudrate=31250)
26+
# midi channel setup
27+
midi_out_channel = 1
28+
# midi setup - UART out on GP0
29+
midi = adafruit_midi.MIDI(
30+
midi_out=uart,
31+
out_channel=(midi_out_channel - 1),
32+
)
33+
34+
# foot switches as keypad object
35+
KEY_PINS = (
36+
board.GP2,
37+
board.GP3,
38+
board.GP4,
39+
board.GP5,
40+
board.GP6,
41+
board.GP7,
42+
board.GP8,
43+
board.GP9,
44+
board.GP10,
45+
board.GP11,
46+
board.GP12,
47+
board.GP13,
48+
board.GP14,
49+
board.GP15,
50+
)
51+
notes = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
52+
keys = keypad.Keys(KEY_PINS, value_when_pressed=False)
53+
54+
# variables & states
55+
MIN_NOTE = 24 # lowest starting octave
56+
MAX_NOTE = 84 # highest starting octave
57+
channel_num = midi.out_channel # track channel
58+
pressed_channel = False # did we try to change the MIDI channel
59+
blink_count = 0 # number of times the LED has blinked
60+
clock = ticks_ms() # time keeping
61+
blink_timer = 500 # blink interval (0.5 seconds)
62+
63+
while True:
64+
event = keys.events.get()
65+
if event:
66+
if event.pressed:
67+
if event.key_number == 12:
68+
# change MIDI channel
69+
channel_num = (channel_num + 1) % 16
70+
midi.out_channel = channel_num
71+
print(channel_num + 1)
72+
pressed_channel = True
73+
led.value = False
74+
blink_count = 0
75+
clock = ticks_ms()
76+
elif event.key_number == 13:
77+
# checks if transposing the first note (C) by 1 octave would exceed the MAX_NOTE
78+
# if it does, wraps the array down to start at MIN_NOTE
79+
# otherwise, transposes all notes up by one octave
80+
notes = [MIN_NOTE + (n - notes[0]) if notes[0] + 12 > MAX_NOTE
81+
else n + 12 for n in notes]
82+
else:
83+
# otherwise send noteOn message
84+
midi.send(NoteOn(notes[event.key_number], 120))
85+
if event.released:
86+
if event.key_number < 12:
87+
midi.send(NoteOff(notes[event.key_number], 120))
88+
if pressed_channel:
89+
# blink LED to show what MIDI channel we're on
90+
if ticks_diff(ticks_ms(), clock) > blink_timer:
91+
if not led.value:
92+
led.value = True
93+
blink_count += 1
94+
else:
95+
led.value = False
96+
clock = ticks_add(clock, blink_timer)
97+
# reset after blinking
98+
if blink_count == (channel_num + 1):
99+
pressed_channel = False
100+
blink_count = 0
101+
led.value = True

0 commit comments

Comments
 (0)