# MIDI Cable # Black - Data # White - VCC 3.3v # Brown - GND import time import board import busio import adafruit_midi # from adafruit_midi.control_change import ControlChange from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn bpm = 120 def init(): print("init") global midi uart = busio.UART(board.TX, board.RX, baudrate=31250, timeout=0.001) # init UART midi_in_channel = 2 midi_out_channel = 1 midi = adafruit_midi.MIDI( midi_in=uart, midi_out=uart, in_channel=(midi_in_channel - 1), out_channel=(midi_out_channel - 1), debug=False, ) print("Default output channel:", midi.out_channel + 1) def trig(note_nr): # print("trig: " + str(note_nr)) midi.send(NoteOn(note_nr, 127)) # MD doesnt need note off # midi.send(NoteOff(note_nr, 0)) def div_to_ns(div): # trig(note_nr) clk_pulse_per_second = 1000000000 beat_per_bar = 4 bar_ns = 60 / bpm * beat_per_bar * clk_pulse_per_second return bar_ns / div def md_note(nr): '''1-16''' md_notes = [36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62] nr = min(nr, 16) nr = max(nr, 1) return md_notes[nr - 1] def md_selftest(): for i in range(1, 16 + 1): trig(md_note(i)) time.sleep(0.01) # NEW # Summing up time deltas is SHIT because of the drift caused by rounding errors, # TOGETHER with the worse part, the INTERFERENCE errors sum up as well # no load - 0.0223318ms / 44779.1Hz # 1 subdiv(1) - 0.041875ms / 23880.6Hz # 4 subdiv(1-8) - 0.112662ms / 8876.11Hz # 8 subdiv(1-8) - 0.159569ms / 6266.89Hz # 16 subdiv(1-16) - 27.792ms / 35.9816Hz def main(): print("main") nr_tracks = 8 clk_now = time.monotonic_ns() clk_last = [] clk_next = [] clk_inc = [] for i in range(0, nr_tracks): clk_inc.append(div_to_ns(i+1)) clk_last.append(clk_now) clk_next.append(clk_now + clk_inc[i] ) clk_inc[0] = div_to_ns(1) clk_inc[1] = div_to_ns(2) clk_inc[2] = div_to_ns(3) clk_inc[3] = div_to_ns(4) clk_inc[4] = div_to_ns(5) clk_inc[5] = div_to_ns(6) clk_inc[6] = div_to_ns(7) clk_inc[7] = div_to_ns(8) clk_start = time.monotonic_ns() loop_count = 0 loop_amt = 10000000 # while True: while loop_count < loop_amt: clk_now = time.monotonic_ns() for i in range(0, nr_tracks): if clk_now >= clk_next[i]: trig(md_note(i+1)) clk_last[i] = clk_now clk_next[i] = clk_now + clk_inc[i] loop_count += 1 clk_end = time.monotonic_ns() ms_per_loop = (clk_end - clk_start) / loop_amt / 1000 / 1000 print("{}ms / {}Hz".format(ms_per_loop, 1000 / ms_per_loop)) init() main()