|
| 1 | +# SPDX-FileCopyrightText: 2021 John Park for Adafruit Industries |
| 2 | +# SPDX-License-Identifier: MIT |
| 3 | +# Macropad MIDI Tester |
| 4 | +# Play MIDI notes with keys |
| 5 | +# Click encoder to switch modes |
| 6 | +# Turn encoder to adjust CC, ProgramChange, or PitchBend |
| 7 | +from adafruit_macropad import MacroPad |
| 8 | +from rainbowio import colorwheel |
| 9 | + |
| 10 | +CC_NUM = 74 # select your CC number |
| 11 | + |
| 12 | +macropad = MacroPad(rotation=180) # create the macropad object, rotate orientation |
| 13 | + |
| 14 | +# --- Pixel setup --- # |
| 15 | +key_color = colorwheel(120) # fill with cyan to start |
| 16 | +macropad.pixels.brightness = 0.1 |
| 17 | +macropad.pixels.fill(key_color) |
| 18 | + |
| 19 | +# --- MIDI variables --- |
| 20 | +mode = 0 |
| 21 | +mode_text = ["Patch", ("CC #%s" % (CC_NUM)), "Pitch Bend"] |
| 22 | +midi_values = [0, 16, 8] # bank, cc value, pitch |
| 23 | +# Chromatic scale starting with C3 as bottom left keyswitch (or use any notes you like) |
| 24 | +midi_notes = [ |
| 25 | + 57, 58, 59, |
| 26 | + 54, 55, 56, |
| 27 | + 51, 52, 53, |
| 28 | + 48, 49, 50 |
| 29 | + ] |
| 30 | + |
| 31 | +# --- Display text setup --- |
| 32 | +text_lines = macropad.display_text("Macropad MIDI Tester") |
| 33 | +text_lines[0].text = "Mode: Patch {}".format(midi_values[0]+1) # Patch display offset by 1 |
| 34 | +text_lines[1].text = "Press knob for modes" |
| 35 | +text_lines.show() |
| 36 | + |
| 37 | +last_knob_pos = macropad.encoder # store knob position state |
| 38 | + |
| 39 | + |
| 40 | +while True: |
| 41 | + |
| 42 | + key_event = macropad.keys.events.get() # check for key press or release |
| 43 | + if key_event: |
| 44 | + if key_event.pressed: |
| 45 | + key = key_event.key_number |
| 46 | + macropad.midi.send(macropad.NoteOn(midi_notes[key], 120)) # send midi noteon |
| 47 | + macropad.pixels[key] = colorwheel(90) # light up green |
| 48 | + text_lines[1].text = "NoteOn:{}".format(midi_notes[key]) |
| 49 | + |
| 50 | + if key_event.released: |
| 51 | + key = key_event.key_number |
| 52 | + macropad.midi.send(macropad.NoteOff(midi_notes[key], 0)) |
| 53 | + macropad.pixels[key] = key_color # return to color set by encoder bank value |
| 54 | + text_lines[1].text = "NoteOff:{}".format(midi_notes[key]) |
| 55 | + |
| 56 | + macropad.encoder_switch_debounced.update() # check the knob switch for press or release |
| 57 | + if macropad.encoder_switch_debounced.pressed: |
| 58 | + mode = (mode+1) % 3 |
| 59 | + if mode == 0: |
| 60 | + text_lines[0].text = ("Mode: %s %d" % (mode_text[mode], midi_values[mode]+1)) |
| 61 | + elif mode == 1: |
| 62 | + text_lines[0].text = ("Mode: %s %d" % (mode_text[mode], int(midi_values[mode]*4.1))) |
| 63 | + else: |
| 64 | + text_lines[0].text = ("Mode: %s %d" % (mode_text[mode], midi_values[mode]-8)) |
| 65 | + macropad.red_led = macropad.encoder_switch |
| 66 | + text_lines[1].text = " " # clear the note line |
| 67 | + |
| 68 | + if macropad.encoder_switch_debounced.released: |
| 69 | + macropad.red_led = macropad.encoder_switch |
| 70 | + |
| 71 | + if last_knob_pos is not macropad.encoder: # knob has been turned |
| 72 | + knob_pos = macropad.encoder # read encoder |
| 73 | + knob_delta = knob_pos - last_knob_pos # compute knob_delta since last read |
| 74 | + last_knob_pos = knob_pos # save new reading |
| 75 | + |
| 76 | + if mode == 0: # ProgramChange |
| 77 | + midi_values[mode] = min(max(midi_values[mode] + knob_delta, 0), 127) # delta + minmax |
| 78 | + macropad.midi.send(macropad.ProgramChange(midi_values[mode])) # midi send ProgramChange |
| 79 | + key_color = colorwheel(midi_values[mode]+120) # change key_color as patches change |
| 80 | + macropad.pixels.fill(key_color) |
| 81 | + text_lines[0].text = ("Mode: %s %d" % (mode_text[mode], midi_values[mode]+1)) |
| 82 | + |
| 83 | + if mode == 1: # CC |
| 84 | + midi_values[mode] = min(max(midi_values[mode] + knob_delta, 0), 31) # scale the value |
| 85 | + macropad.midi.send(macropad.ControlChange(CC_NUM, int(midi_values[mode]*4.1))) |
| 86 | + text_lines[0].text = ("Mode: %s %d" % (mode_text[mode], int(midi_values[mode]*4.1))) |
| 87 | + |
| 88 | + if mode == 2: # PitchBend |
| 89 | + midi_values[mode] = min(max(midi_values[mode] + knob_delta, 0), 15) # smaller range |
| 90 | + macropad.midi.send(macropad.PitchBend((midi_values[mode]*1024))) # range * mult = 16384 |
| 91 | + text_lines[0].text = ("Mode: %s %d" % (mode_text[mode], midi_values[mode]-8)) |
| 92 | + |
| 93 | + last_knob_pos = macropad.encoder |
0 commit comments