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