Simple test
Ensure your device works with this simple test.
examples/keymanager_simpletest.py
1# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2# SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple
3#
4# SPDX-License-Identifier: Unlicense
5
6from relic_keymanager import Keyboard
7
8keyboard = Keyboard()
9
10keyboard.on_voice_press = lambda voice: print(f"Pressed: {voice.note.notenum:d}")
11keyboard.on_voice_release = lambda voice: print(f"Released: {voice.note.notenum:d}")
12
13for i in range(1, 4):
14 keyboard.append(i)
15for i in range(3, 0, -1):
16 keyboard.remove(i)
Keys
Use a digital input to trigger a note.
examples/keymanager_keys.py
1# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2# SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple
3#
4# SPDX-License-Identifier: Unlicense
5
6import asyncio
7
8import board
9from keypad import Keys
10
11from relic_keymanager import Keyboard
12
13keyboard = Keyboard(
14 keys=Keys((board.USER_SW,), value_when_pressed=False, pull=False),
15)
16
17keyboard.on_voice_press = lambda voice: print(f"Pressed: {voice.note.notenum:d}")
18keyboard.on_voice_release = lambda voice: print(f"Released: {voice.note.notenum:d}")
19
20asyncio.run(keyboard.update())
Arpeggiator
Demonstration of the arpeggiator.
examples/keymanager_arpeggiator.py
1# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2# SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple
3#
4# SPDX-License-Identifier: Unlicense
5
6import asyncio
7
8from relic_keymanager import Arpeggiator, ArpeggiatorMode, Keyboard, TimerStep
9
10keyboard = Keyboard()
11
12keyboard.on_voice_press = lambda voice: print(f"Pressed: {voice.note.notenum:d}")
13
14keyboard.arpeggiator = Arpeggiator(steps=TimerStep.QUARTER, mode=ArpeggiatorMode.UPDOWN)
15keyboard.arpeggiator.octaves = 1
16keyboard.arpeggiator.active = True
17
18for i in range(1, 4):
19 keyboard.append(i)
20
21asyncio.run(keyboard.arpeggiator.update())
Sequencer
Demonstration of the sequencer.
examples/keymanager_sequencer.py
1# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2# SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple
3#
4# SPDX-License-Identifier: Unlicense
5
6import asyncio
7
8from relic_keymanager import Keyboard, Sequencer
9
10keyboard = Keyboard()
11
12keyboard.on_voice_press = lambda voice: print(f"Pressed: {voice.note.notenum:d}")
13
14sequencer = Sequencer()
15sequencer.active = True
16
17for i in range(4):
18 sequencer.set_note(i * 4, 1)
19 sequencer.set_note(i * 4 + 2, i % 2 + 2)
20
21sequencer.on_press = lambda notenum, velocity: keyboard.append(notenum, velocity)
22sequencer.on_release = lambda notenum: keyboard.remove(notenum)
23
24asyncio.run(sequencer.update())
synthio & MIDI
Use the relic_keymanager.Keyboard class to help allocate MIDI notes into a limited set of
synthio.Note objects using USB MIDI input and DAC/PWM audio playback.
examples/keymanager_synthio.py
1# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2# SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple
3#
4# SPDX-License-Identifier: Unlicense
5
6import adafruit_midi
7import audiopwmio
8import board
9import digitalio
10import synthio
11import usb_midi
12from adafruit_midi.control_change import ControlChange
13from adafruit_midi.note_off import NoteOff
14from adafruit_midi.note_on import NoteOn
15from adafruit_midi.pitch_bend import PitchBend
16
17from relic_keymanager import Keyboard
18
19led = digitalio.DigitalInOut(board.LED)
20led.direction = digitalio.Direction.OUTPUT
21
22audio = audiopwmio.PWMAudioOut(board.A0)
23synth = synthio.Synthesizer()
24audio.play(synth)
25
26notes = tuple(
27 [
28 synthio.Note(
29 frequency=440.0,
30 bend=synthio.Math(
31 synthio.MathOperation.SUM, synthio.LFO(rate=8.0, scale=0.0), 0.0, 0.0
32 ),
33 )
34 for i in range(4)
35 ]
36)
37
38keyboard = Keyboard(max_voices=len(notes))
39
40
41def press(voice):
42 notes[voice.index].frequency = synthio.midi_to_hz(voice.note.notenum)
43 synth.press(notes[voice.index])
44 led.value = True
45
46
47keyboard.on_voice_press = press
48
49
50def release(voice):
51 synth.release(notes[voice.index])
52 if not synth.pressed:
53 led.value = False
54
55
56keyboard.on_voice_release = release
57
58midi = adafruit_midi.MIDI(
59 midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0
60)
61
62while True:
63 msg = midi.receive()
64 if isinstance(msg, NoteOn) and msg.velocity != 0:
65 keyboard.append(msg.note, msg.velocity / 127.0)
66 elif isinstance(msg, NoteOff) or (isinstance(msg, NoteOn) and msg.velocity == 0):
67 keyboard.remove(msg.note)
68 elif isinstance(msg, ControlChange):
69 if msg.control == 1: # Mod Wheel
70 for note in notes:
71 note.bend.a.scale = msg.value / 127 / 12.0
72 elif msg.control == 64: # Sustain Pedal
73 keyboard.sustain = msg.value >= 64
74 elif isinstance(msg, PitchBend):
75 for note in notes:
76 note.bend.b = (msg.pitch_bend / 8192) - 1.0