def test_send_basic_sequences(self): # def printit(buffer, len): # print(buffer[0:len]) mockedPortOut = Mock() # mockedPortOut.write = printit m = adafruit_midi.MIDI(midi_out=mockedPortOut, out_channel=2) # Test sending some NoteOn and NoteOff to various channels nextcall = 0 # Test sequences with list syntax and pass a tuple too note_list = [ NoteOn(0x6C, 0x51), NoteOn(0x70, 0x52), NoteOn(0x73, 0x53) ] note_tuple = tuple(note_list) m.send(note_list, channel=10) self.assertEqual( mockedPortOut.write.mock_calls[nextcall], call(b"\x9a\x6c\x51\x9a\x70\x52\x9a\x73\x53", 9), "The implementation writes in one go, single 9 byte write expected", ) nextcall += 1 m.send(note_tuple, channel=11) self.assertEqual( mockedPortOut.write.mock_calls[nextcall], call(b"\x9b\x6c\x51\x9b\x70\x52\x9b\x73\x53", 9), "The implementation writes in one go, single 9 byte write expected", ) nextcall += 1
def MIDI_mocked_receive(in_c, data, read_sizes): usb_data = bytearray(data) chunks = read_sizes chunk_idx = 0 def read(length): nonlocal usb_data, chunks, chunk_idx # pylint: disable=no-else-return if length != 0 and chunk_idx < len(chunks): # min() to ensure we only read what's asked for and present poppedbytes = usb_data[0:min(length, chunks[chunk_idx])] usb_data = usb_data[len(poppedbytes):] if length >= chunks[chunk_idx]: chunk_idx += 1 else: chunks[chunk_idx] -= len(poppedbytes) return bytes(poppedbytes) else: return bytes() mockedPortIn = Mock() mockedPortIn.read = read m = adafruit_midi.MIDI(midi_out=None, midi_in=mockedPortIn, out_channel=in_c, in_channel=in_c) return m
def test_send_basic_single(self): # def printit(buffer, len): # print(buffer[0:len]) mockedPortOut = Mock() # mockedPortOut.write = printit m = adafruit_midi.MIDI(midi_out=mockedPortOut, out_channel=2) # Test sending some NoteOn and NoteOff to various channels nextcall = 0 m.send(NoteOn(0x60, 0x7F)) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x92\x60\x7f", 3)) nextcall += 1 m.send(NoteOn(0x64, 0x3F)) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x92\x64\x3f", 3)) nextcall += 1 m.send(NoteOn(0x67, 0x1F)) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x92\x67\x1f", 3)) nextcall += 1 m.send(NoteOn(0x60, 0x00)) # Alternative to NoteOff self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x92\x60\x00", 3)) nextcall += 1 m.send(NoteOff(0x64, 0x01)) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x82\x64\x01", 3)) nextcall += 1 m.send(NoteOff(0x67, 0x02)) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x82\x67\x02", 3)) nextcall += 1 # Setting channel to non default m.send(NoteOn(0x6C, 0x7F), channel=9) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x99\x6c\x7f", 3)) nextcall += 1 m.send(NoteOff(0x6C, 0x7F), channel=9) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x89\x6c\x7f", 3)) nextcall += 1
def __init__(self): make_argumented_key( names=('MIDI_CC', ), validator=ControlChange, on_press=self.on_press, ) make_argumented_key( names=('MIDI_NOTE', ), validator=midiNoteValidator, on_press=self.note_on, on_release=self.note_off, ) make_argumented_key( names=('MIDI_PB', ), validator=PitchBend, on_press=self.on_press, ) make_argumented_key( names=('MIDI_PC', ), validator=ProgramChange, on_press=self.on_press, ) make_argumented_key( names=('MIDI_START', ), validator=Start, on_press=self.on_press, ) make_argumented_key( names=('MIDI_STOP', ), validator=Stop, on_press=self.on_press, ) try: self.midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0) except IndexError: self.midi = None # if debug_enabled: print('No midi device found.')
def test_send_badnotes(self): mockedPortOut = Mock() m = adafruit_midi.MIDI(midi_out=mockedPortOut, out_channel=2) # Test sending some NoteOn and NoteOff to various channels nextcall = 0 m.send(NoteOn(60, 0x7F)) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x92\x3c\x7f", 3)) nextcall += 1 with self.assertRaises(ValueError): m.send(NoteOn(64, 0x80)) # Velocity > 127 - illegal value with self.assertRaises(ValueError): m.send(NoteOn(67, -1)) # test after exceptions to ensure sending is still ok m.send(NoteOn(72, 0x7F)) self.assertEqual(mockedPortOut.write.mock_calls[nextcall], call(b"\x92\x48\x7f", 3)) nextcall += 1
def MIDI_mocked_both_loopback(in_c, out_c): usb_data = bytearray() def write(buffer, length): nonlocal usb_data usb_data.extend(buffer[0:length]) def read(length): nonlocal usb_data poppedbytes = usb_data[0:length] usb_data = usb_data[len(poppedbytes):] return bytes(poppedbytes) mockedPortIn = Mock() mockedPortIn.read = read mockedPortOut = Mock() mockedPortOut.write = write m = adafruit_midi.MIDI(midi_out=mockedPortOut, midi_in=mockedPortIn, out_channel=out_c, in_channel=in_c) return m
def MIDI_mocked_both_loopback(in_c, out_c): # pylint: disable=invalid-name # pylint: enable=invalid-name usb_data = bytearray() def write(buffer, length): nonlocal usb_data usb_data.extend(buffer[0:length]) def read(length): nonlocal usb_data poppedbytes = usb_data[0:length] usb_data = usb_data[len(poppedbytes):] return bytes(poppedbytes) mockedportin = Mock() mockedportin.read = read mockedportout = Mock() mockedportout.write = write midi = adafruit_midi.MIDI(midi_out=mockedportout, midi_in=mockedportin, out_channel=out_c, in_channel=in_c) return midi
import time import random import adafruit_midi midi = adafruit_midi.MIDI(out_channel=0) print("Midi test") print("Default output channel:", midi.out_channel) print("Listening on input channel:", midi.in_channel) while True: midi.note_on(44, 120) midi.note_off(44, 120) midi.control_change(3, 44) midi.pitch_bend(random.randint(0, 16383)) time.sleep(1)
import time import board import busio from simpleio import map_range from analogio import AnalogIn from digitalio import DigitalInOut, Direction import usb_midi import adafruit_midi # MIDI protocol encoder/decoder library from adafruit_midi.control_change import ControlChange USB_MIDI_channel = 1 # pick your USB MIDI out channel here, 1-16 # pick your classic MIDI channel for sending over UART serial TX/RX CLASSIC_MIDI_channel = 2 usb_midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=USB_MIDI_channel - 1) # use DIN-5 or TRS MIDI jack on TX/RX for classic MIDI uart = busio.UART(board.TX, board.RX, baudrate=31250, timeout=0.001) # initialize UART classic_midi = adafruit_midi.MIDI(midi_out=uart, midi_in=uart, out_channel=CLASSIC_MIDI_channel - 1, debug=False) led = DigitalInOut(board.D13) # activity indicator led.direction = Direction.OUTPUT knob_count = 16 # Set the total number of potentiometers used # Create the input objects list for potentiometers knob = []
def test_no_inout(self): # constructor likes a bit of in out with self.assertRaises(ValueError): adafruit_midi.MIDI()
import usb_midi import adafruit_midi from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn from adafruit_midi.pitch_bend import PitchBend from adafruit_midi.control_change import ControlChange from adafruit_debouncer import Debouncer midi_base_note = 48 # 48 = C3 midi_velocity = 64 # midpoint midi_channel = 0 midi_cc_num = 1 # standard modwheel touch_threshold_adjust = 500 midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1]) touch_pins = ( board.GP0, board.GP1, board.GP2, board.GP3, board.GP4, board.GP5, board.GP6, board.GP7, board.GP8, board.GP9, board.GP10, board.GP11, board.GP12,
group.append(lbl_title) lbl_info = label.Label(font, text=" no clock ", color=0xFFFF00) lbl_info.x = 46 lbl_info.y = 68 group.append(lbl_info) lbl_cmd = label.Label(font, text=" ", color=0xFF8000) lbl_cmd.x = 55 lbl_cmd.y = 110 group.append(lbl_cmd) display.show(group) #start receiving MIDI messages from USB, any MIDI channel midi = adafruit_midi.MIDI(midi_in=usb_midi.ports[0], in_channel="ALL") print("Midi Clock Monitor 1.0") ticks = 0 start = time.monotonic() # start the timer to measure clock ticks while True: msg = midi.receive() if msg is not None: if isinstance(msg, TimingClock): # receive a MIDI tick message ticks += 1 if ticks == 24: # midi clock is 24 ticks per beat beat_time = float(time.monotonic() - start) bpm = str(math.floor(60 / beat_time))
import busio import adafruit_midi import usb_midi from adafruit_midi.control_change import ControlChange from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn from adafruit_midi.program_change import ProgramChange uart = busio.UART(board.GP0, board.GP1, baudrate=31250, timeout=0.001) # init UART midi_in_channel = 2 midi_out_channel = 1 midi0 = adafruit_midi.MIDI( midi_in=uart, midi_out=uart, in_channel=(midi_in_channel - 1), out_channel=(midi_out_channel - 1), debug=False, ) midi1 = adafruit_midi.MIDI(midi_out=usb_midi.ports[1],midi_in=usb_midi.ports[0], out_channel=0, in_channel=4) midi = midi1 def setupMidi(mode): if mode == "MIDI": midi = midi0 elif mode == "USB": midi = midi1 def sendCC(program, value): midi.send(ControlChange(program, value))
# simple_test import time import random import usb_midi import adafruit_midi from adafruit_midi.control_change import ControlChange from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn from adafruit_midi.pitch_bend import PitchBend midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0) print("Midi test") # Convert channel numbers at the presentation layer to the ones musicians use print("Default output channel:", midi.out_channel + 1) print("Listening on input channel:", midi.in_channel + 1 if midi.in_channel is not None else None) while True: midi.send(NoteOn(44, 120)) # G sharp 2nd octave time.sleep(0.25) a_pitch_bend = PitchBend(random.randint(0, 16383)) midi.send(a_pitch_bend) time.sleep(0.25) # note how a list of messages can be used midi.send([NoteOff("G#2", 120), ControlChange(3, 44)]) time.sleep(0.5)
NeoTrellis(i2c_bus, False, addr=0x2F)] ] trellis = MultiTrellis(trelli) # some color definitions OFF = (0, 0, 0) # these are base 0 in_channels = (0,) # listening on channel 1 out_channel = 1 # sending through channel 2 midi = adafruit_midi.MIDI( midi_in=usb_midi.ports[0], midi_out=usb_midi.ports[1], in_channel=in_channels, out_channel=out_channel, in_buf_size=64 ) UPPER_LEFT = 0 V = 100 # default color value PAGE = 'main' CC_MAP = { 'time': 14, 'mix': 15, 'length': 16, 'drip_modify': 17, 'clock': 18, 'loop_modify': 19,
from adafruit_midi.control_change import ControlChange from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn from adafruit_midi.pitch_bend import PitchBend from adafruit_midi.polyphonic_key_pressure import PolyphonicKeyPressure from adafruit_midi.program_change import ProgramChange from adafruit_midi.start import Start from adafruit_midi.stop import Stop from adafruit_midi.system_exclusive import SystemExclusive from adafruit_midi.midi_message import MIDIUnknownEvent from cedargrove_MIDI_util import * UART = busio.UART(board.TX, board.RX, baudrate=31250, timeout=0.001) midi = adafruit_midi.MIDI(midi_in=UART, midi_out=UART, in_channel=0, out_channel=0) # 0 is MIDI channel 1 print("Simple_MIDI_Sniffer.py 2019-07-16 CedarGrove") # Convert channel numbers at the presentation layer to the ones musicians use print("Input channel:", midi.in_channel + 1) t0 = time.monotonic_ns() tempo = 0 while True: msg = midi.receive() if msg is not None:
def __init__(self, *args, **kwargs): super(Sequencer, self).__init__(*args, **kwargs) # Holds the list of MIDI channels for the tracks. self.midi_channels = [] # Set the MIDI channels up. for channel in MIDI_CHANNELS: midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=channel) self.midi_channels.append(midi) # These keys represent the steps on the tracks. self.track_keys = [] for i in range(len(TRACK_KEYS)): track_key = self.keys[TRACK_KEYS[i]] track_key.index = i self.track_keys.append(track_key) # These keys select and change the current track. self.track_select_keys = [] for i in range(len(TRACK_SELECTOR_KEYS)): track_select_key = self.keys[TRACK_SELECTOR_KEYS[i]] track_select_key.rgb = TRACK_COLOURS[i] self.track_select_keys.append(track_select_key) self.track_select_keys_held = [False, False, False, False] self.track_select_active = False # Holds the list of tracks, a set of Track instances. self.tracks = [] # Set the tracks up. for i in range(4): track = Track(self, i, i, TRACK_COLOURS[i]) self.tracks.append(track) # Speed attributes. self.bpm = BPM self.tempo_selector = self.keys[TEMPO_SELECTOR] self.tempo_selector.set_led(*TEMPO_SELECTOR_COLOUR) self.tempo_select_active = False self.tempo_down = self.keys[TEMPO_DOWN] self.tempo_up = self.keys[TEMPO_UP] # Step related stuff self.num_steps = 8 self.this_step_num = 0 self.last_step_num = 0 self.steps_held = [] # Note change attributes. self.note_down = self.keys[NOTE_DOWN] self.note_up = self.keys[NOTE_UP] self.velocity_down = self.keys[VELOCITY_DOWN] self.velocity_up = self.keys[VELOCITY_UP] # Is the sequencer running? self.running = False # Step time assumes the BPM is based on quarter notes. self.step_time = 60.0 / self.bpm / (self.num_steps / 2) self.last_step_time = time.monotonic() # Set the default starting track to track 0 self.current_track = 0 # The start stop key. self.start_stop = self.keys[START_STOP] self.start_stop.set_led(*STOP_COLOUR) self.start_stop_held = False # The track selector key. self.track_selector = self.keys[TRACK_SELECTOR] self.track_selector.set_led(*TRACK_SELECTOR_COLOUR) # Set the key hold time for all the keys. A little shorter than the # default for Keybow. Makes controlling the sequencer a bit more fluid. for key in self.keys: key.hold_time = KEY_HOLD_TIME # Attach step_select function to keys in track steps. If pressed it # toggles the state of the step. for key in self.track_keys: @self.on_release(key) def step_select(key): if self.tracks[self.current_track].active: if not key.held: step = self.tracks[self.current_track].steps[key.index] step.toggle() if not step.active: current_note = step.note self.midi_channels[track.channel].send( NoteOff(current_note, 0)) step.note = DEFAULT_NOTE step.velocity = DEFAULT_VELOCITY else: self.steps_held.remove(key.index) self.note_down.led_off() self.note_up.led_off() self.velocity_down.led_off() self.velocity_up.led_off() self.update_track_select_keys(True) # When step held, toggle on the note and velocity up/down keys. @self.on_hold(key) def step_change(key): if self.tracks[self.current_track].active: self.steps_held.append(key.index) self.note_down.set_led(*NOTE_DOWN_COLOUR) self.note_up.set_led(*NOTE_UP_COLOUR) self.velocity_down.set_led(*VELOCITY_DOWN_COLOUR) self.velocity_up.set_led(*VELOCITY_UP_COLOUR) self.update_track_select_keys(False) # Attach hold function to track selector key that sets it active and # lights the track select keys. @self.on_hold(self.track_selector) def track_selector_hold(key): self.track_select_active = True for track in self.tracks: track.update_track_select_key = True # Attach release function to track selector key that sets it inactive # and turns track select LEDs off. @self.on_release(self.track_selector) def track_selector_release(key): self.track_select_active = False self.update_track_select_keys(True) # Handles track select/mute, tempo down/up, note down/up. # # If the tempo selector key (second from left, blue, on the bottom row) # is held, pressing the tempo keys (the left two keys on the second # bottom row, lit blue and pink) shifts the tempo down or up by # 5 bpm each time it is pressed, with a lower limit of 5 BPM and upper # limit of 200 BPM. # # If notes are held, then the four track select keys allow the held # notes MIDI note number to be shifted down/up (track select keys 0 # and 1 respectively), or MIDI velocity to be shifted down/up (track # select keys 2 and 3 respectively). # # If the track selector is not held, tapping this track button toggles #the track on/off. for key in self.track_select_keys: @self.on_press(key) def track_select_press(key): index = TRACK_SELECTOR_KEYS.index(key.number) if self.track_select_active: self.current_track = index elif self.tempo_select_active: if index == 0: if self.bpm > 5: self.bpm -= 5 elif index == 1: if self.bpm < 200: self.bpm += 5 elif len(self.steps_held): for i in self.steps_held: step = self.tracks[self.current_track].steps[i] if index == 0 or index == 1: step.last_notes.append(step.note) step.note_changed = True if index == 0: if step.note > 0: step.note -= 1 elif index == 1: if step.note < MAX_NOTE: step.note += 1 elif index == 2: if step.velocity > 0 + VELOCITY_STEP: step.velocity -= VELOCITY_STEP elif index == 3: if step.velocity <= MAX_VELOCITY - VELOCITY_STEP: step.velocity += VELOCITY_STEP else: self.tracks[index].active = not self.tracks[index].active self.tracks[index].update_track_select_key = True # Handlers to hold held states of track select keys. for key in self.track_select_keys: @self.on_hold(key) def track_select_key_hold(key): index = TRACK_SELECTOR_KEYS.index(key.number) self.track_select_keys_held[index] = True @self.on_release(key) def track_select_key_release(key): index = TRACK_SELECTOR_KEYS.index(key.number) self.track_select_keys_held[index] = False # Attach press function to start/stop key that toggles whether the # sequencer is running and toggles its colour between green (running) # and red (not running). @self.on_press(self.start_stop) def start_stop_toggle(key): if not self.track_select_active: if self.running: self.running = False key.set_led(*STOP_COLOUR) else: self.running = True key.set_led(*START_COLOUR) # Attach hold function, so that when the track selector key is held and # the start/stop key is also held, clear all of the steps on all of the # tracks. If a track select key is held, then clear just that track. @self.on_hold(self.start_stop) def start_stop_hold(key): self.start_stop_held = True if self.track_select_active: if not any(self.track_select_keys_held): self.clear_tracks() for track in self.tracks: track.midi_panic() else: for i, state in enumerate(self.track_select_keys_held): if state: self.tracks[i].clear_steps() @self.on_release(self.start_stop) def start_stop_release(key): self.start_stop_held = False # Attach hold function that lights the tempo down/up keys when the # tempo selector key is held. @self.on_hold(self.tempo_selector) def tempo_selector_hold(key): self.tempo_select_active = True self.tempo_down.set_led(*TEMPO_DOWN_COLOUR) self.tempo_up.set_led(*TEMPO_UP_COLOUR) self.track_select_keys[2].led_off() self.track_select_keys[3].led_off() self.update_track_select_keys(False) # Attach release function that furns off the tempo down/up LEDs. @self.on_release(self.tempo_selector) def tempo_selector_release(key): self.tempo_select_active = False self.tempo_down.led_off() self.tempo_up.led_off() self.update_track_select_keys(True)
square_offset = 0 - square_offset sample = random.randint(midpoint + square_offset - noise_vol, midpoint + square_offset + noise_vol) noise_wave_raw[idx] = sample noise_wave_raw[0] = midpoint # start at midpoint #noise_wave_raw = array.array("H", # [random.randint(midpoint-5000, midpoint+5000) # for x in range(sample_len)]) #noise_wave_raw = array.array("h", [0] * sample_len) noise_wave = audioio.RawSample(noise_wave_raw) del noise_wave_raw midi_channel = 10 midi = adafruit_midi.MIDI(midi_in=usb_midi.ports[0], in_channel=midi_channel-1, in_buf_size=6) last_note = None # Read any incoming MIDI messages (events) over USB # looking for note on, note off to turn noise on and off while True: #gc.collect() #print(gc.mem_free()) #print(gc.mem_free()) msg = midi.receive() if isinstance(msg, NoteOn) and msg.velocity != 0: note_sample_rate = round(base_sample_rate * math.pow(2, (msg.note - midi_note_A4) / 12.0)) if note_sample_rate > max_sample_rate:
eg2pwm = twomegfixedpwm(board.A3) eg1pwm = twomegfixedpwm(board.A2) if eg1pwm is None or eg2pwm is None: print("Shared couter PWM failure II - soft/hard reset suggested") else: print("High frequency shared counter PWM initialised ok") osc1 = pulseio.PWMOut(board.A1, duty_cycle=2**15, frequency=440, variable_frequency=True) osc2 = pulseio.PWMOut(board.A6, duty_cycle=2**15, frequency=441, variable_frequency=True) #dac = analogio.AnalogOut(board.A0) dac = audioio.AudioOut(board.A0) ### 0 is MIDI channel 1 midi = adafruit_midi.MIDI(in_channel=0) #veltovol = int(65535 / 127) ### Multiplier for MIDI velocity ^ 0.40 ### 0.5 would be correct for velocity = power ### but 0.4 sounds more natural - ymmv velcurve = 0.40 veltovolc040 = 9439 # pitchbendrange in semitones - often 2 or 12 pitchbendmultiplier = 12 / 8192 pitchbendvalue = 8192 # mid point - no bend # Commenting out debug as I just got a Memory Error linked with code size :( # TODO - look into mpy vs py saving and generation #debug = True
# pylint: disable=E0401 disable=E0611 disable=E1101 # ignore load error on circuitpython modules import usb_midi import adafruit_midi # pylint: disable=W0611 # unused modules are still important for midi parsing from adafruit_midi.timing_clock import TimingClock from adafruit_midi.channel_pressure import ChannelPressure from adafruit_midi.control_change import ControlChange from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn from adafruit_midi.pitch_bend import PitchBend from adafruit_midi.polyphonic_key_pressure import PolyphonicKeyPressure from adafruit_midi.program_change import ProgramChange from adafruit_midi.start import Start from adafruit_midi.stop import Stop from adafruit_midi.system_exclusive import SystemExclusive from adafruit_midi.midi_message import MIDIUnknownEvent portIn = usb_midi.ports[0] midi = adafruit_midi.MIDI(midi_in=portIn, in_channel=0) def read_midi(): """ A short description. """ return midi.receive()
from adafruit_midi.pitch_bend import PitchBend from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn # uart setup uart = busio.UART(board.TX, board.RX, baudrate=31250) # midi channel setup midi_in_channel = 1 midi_out_channel = 1 # midi setup # UART is setup as the input # USB is setup as the output midi = adafruit_midi.MIDI( midi_in=uart, midi_out=usb_midi.ports[1], in_channel=(midi_in_channel - 1), out_channel=(midi_out_channel - 1), debug=False, ) print("MIDI UART In/USB Out") print("Default output channel:", midi.out_channel + 1) # array of message types messages = (NoteOn, NoteOff, PitchBend, ControlChange) while True: # receive MIDI input from UART msg = midi.receive() # if the input is a recognized message...
from adafruit_midi.channel_pressure import ChannelPressure from adafruit_midi.control_change import ControlChange from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn from adafruit_midi.pitch_bend import PitchBend from adafruit_midi.polyphonic_key_pressure import PolyphonicKeyPressure from adafruit_midi.program_change import ProgramChange from adafruit_midi.start import Start from adafruit_midi.stop import Stop from adafruit_midi.system_exclusive import SystemExclusive from adafruit_midi.midi_message import MIDIUnknownEvent from cedargrove_MIDI_util import * UART = busio.UART(board.TX, board.RX, baudrate=31250, timeout=0.001) midi = adafruit_midi.MIDI(midi_in=UART, in_channel=0) # 0 is MIDI channel 1 print("basic MIDI sniffer.py 2019-06-18 CedarGrove") # Convert channel numbers at the presentation layer to the ones musicians use print("Input channel:", midi.in_channel + 1 ) t0 = time.monotonic_ns() tempo = 0 while True: msg = midi.receive() if msg is not None: # print("Time: ",time.monotonic()) # time stamp
height=1, tile_height=16, tile_width=16, default_tile=EMPTY) blinka_grid.x = 112 blinka_grid.y = 0 splash.append(blinka_grid) # imports MIDI # USB MIDI: # midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0) # UART MIDI: midi = adafruit_midi.MIDI(midi_out=busio.UART(board.TX, board.RX, baudrate=31250), out_channel=0) # potentiometer pin setup key_pot = AnalogIn(board.A1) mode_pot = AnalogIn(board.A2) beat_pot = AnalogIn(board.A3) bpm_slider = AnalogIn(board.A4) mod_pot = AnalogIn(board.A5) # run switch setup run_switch = DigitalInOut(board.D5) run_switch.direction = Direction.INPUT run_switch.pull = Pull.UP # arrays of notes in each key
### key trigger time, key release time, volume at release] oscvcas.append([osc1, vca1pwm, -1, 0, 0, 0.0, 0.0, 0.0]) oscvcas.append([osc2, vca2pwm, -1, 0, 0, 0.0, 0.0, 0.0]) ### Not in use #dac = analogio.AnalogOut(board.A0) ### TODO implement volume per channel based on midi cc 7 ### 0 is MIDI channel 1 ### This is listening on channels 1 and 2 ### Testing with bigger in_bug_size as MIDI file driven ### pitch bends may be overwhelming buffering causing byte loss ### 600 helps a bit but obviously audible issue with processing ### slowing down on bursty pitch bends midi = adafruit_midi.MIDI(in_channel=(0,1), debug=False, in_buf_size=30) #veltovol = int(65535 / 127) ### Multiplier for MIDI velocity ^ 0.40 ### 0.5 would be correct for velocity = power ### but 0.4 sounds more natural - ymmv velcurve = 0.40 veltovolc040 = 9439 # pitchbendrange in semitones - often 2 or 12 pitchrange = 2 pitchbendmultiplier = pitchrange / 8192 pitchbendvalue = 8192 # mid point - no bend # Commenting out debug as I just got a Memory Error linked with code size :( # TODO - look into mpy vs py saving and generation
from adafruit_midi.note_off import NoteOff # led setup cs = DigitalInOut(board.GP17) cs.direction = Direction.OUTPUT cs.value = 0 pixels = adafruit_dotstar.DotStar(board.GP18, board.GP19, 16, brightness=0.5, auto_write=True) # button setup i2c = busio.I2C(board.GP5, board.GP4) device = I2CDevice(i2c, 0x20) # midi setup midi = [adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=ch) for ch in range(16)] # enums class ButtonState: PRESSED = 1 LONGPRESSED = 2 RELEASED = 3 class ButtonMode: PATTERN = 1 NOTE_CHOOSER = 2 CHANNEL_CHOOSER = 3 WAIT = 4
from adafruit_midi.note_on import NoteOn from adafruit_midi.pitch_bend import PitchBend import adafruit_ble_midi # Use default HID descriptor midi_service = adafruit_ble_midi.MIDIService() advertisement = ProvideServicesAdvertisement(midi_service) ble = adafruit_ble.BLERadio() if ble.connected: for c in ble.connections: c.disconnect() midi = adafruit_midi.MIDI(midi_out=midi_service, midi_in=midi_service, out_channel=0) print("advertising") ble.start_advertising(advertisement) while True: print("Waiting for connection") while not ble.connected: pass print("Connected") while ble.connected: midi_in = midi.receive() while midi_in: if not isinstance(midi_in, MIDIUnknownEvent): print(time.monotonic(), midi_in) midi_in = midi.receive()
) # start on the last one so first time it is pressed it goes to first cc_x = 0 cc_y = 0 cc_prox = 0 # Use default HID descriptor midi_service = adafruit_ble_midi.MIDIService() advertisement = ProvideServicesAdvertisement(midi_service) ble = adafruit_ble.BLERadio() if ble.connected: for c in ble.connections: c.disconnect() midi = adafruit_midi.MIDI(midi_out=midi_service, out_channel=midi_channel - 1) print("advertising") ble.name = "CLUE BLE MIDI" ble.start_advertising(advertisement) clue.display.brightness = 1.0 clue.pixel.brightness = 0.2 screen = displayio.Group() ORANGE = 0xCE6136 GRAY = 0x080808 BLACK = 0x121212 BLUE = 0x668190 SILVER = 0xAAAAAA BROWN = 0x805D40
oscvcas.append([osc2, vca2pwm, -1, 0, 0, 0.0, 0.0, 0.0]) ### Audio output via DAC on A0 audio_out_a0 = audioio.AudioOut(board.A0) ### 0 is MIDI channel 1 ### This is listening on channels 1 and 2 ### Testing with bigger in_bug_size as MIDI file driven ### pitch bends may be overwhelming buffering causing byte loss ### 600 helps a bit but obviously audible issue with processing ### slowing down on bursty pitch bends duochannels = (0,1) extrachannel = (2,) combinedchannels = duochannels + extrachannel channels = len(combinedchannels) midi = adafruit_midi.MIDI(in_channel=combinedchannels, debug=False, in_buf_size=30) #veltovol = int(65535 / 127) ### Multiplier for MIDI velocity ^ 0.40 ### 0.5 would be correct for velocity = power ### but 0.4 sounds more natural - ymmv velcurve = 0.40 veltovolc040 = 9439 ### volume is integer between 0 and 127 ### volduo is the latest value received on protocol ### channel 0, 1 (MIDI channels 1,2) ### volextra is value from protocol channel 2 (MIDI channel 3) volduo = 127 volextra = 127
oled_reset = board.D1 # I2C setup for display # STEMMA I2C setup pre-CP 7.2 i2c = busio.I2C(board.SCL1, board.SDA1) # STEMMA I2C setup for CP 7.2+ # i2c = board.STEMMA_I2C() display_bus = displayio.I2CDisplay(i2c, device_address=0x3D, reset=oled_reset) # midi setup print(usb_midi.ports) midi = adafruit_midi.MIDI( midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0 ) msg = midi.receive() # display width and height setup WIDTH = 128 HEIGHT = 64 BORDER = 5 # display setup display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=WIDTH, height=HEIGHT) splash = displayio.Group() display.show(splash)
# Grand Central MIDI Knobs # for USB MIDI # Reads analog inputs, sends out MIDI CC values # written by John Park with Kattni Rembor and Jan Goolsbey for range and hysteresis code import time import adafruit_midi import board from simpleio import map_range from analogio import AnalogIn print("---Grand Central MIDI Knobs---") midi = adafruit_midi.MIDI(out_channel=0) # Set the output MIDI channel (0-15) knob_count = 16 # Set the total number of potentiometers used # Create the input objects list for potentiometers knob = [] for k in range(knob_count): knobs = AnalogIn(getattr(board, "A{}".format(k))) # get pin # attribute, use string formatting knob.append(knobs) # CC range list defines the characteristics of the potentiometers # This list contains the input object, minimum value, and maximum value for each knob. # example ranges: # 0 min, 127 max: full range control voltage # 36 (C2) min, 84 (B5) max: 49-note keyboard # 21 (A0) min, 108 (C8) max: 88-note grand piano cc_range = [ (36, 84), # knob 0: C2 to B5: 49-note keyboard (36, 84), # knob 1