Simple test
Show how to send MIDI messages.
examples/tmidi_simpletest.py
1# SPDX-FileCopyrightText: Copyright (c) 2024 Tod Kurt
2#
3# SPDX-License-Identifier: MIT
4
5# This example outputs MIDI notes over USB MIDI
6
7import time
8import random
9import usb_midi
10
11import tmidi
12
13midi_channel = 1 # which MIDI channel to send on
14
15midi_usb = tmidi.MIDI(midi_in=usb_midi.ports[0], midi_out=usb_midi.ports[1])
16
17while True:
18 notenum = random.randint(36, 72)
19 velocity = 127
20
21 msg_on = tmidi.Message(tmidi.NOTE_ON, notenum, velocity, channel=midi_channel - 1)
22 print("sending note on msg:", msg_on)
23 midi_usb.send(msg_on)
24 time.sleep(0.1)
25
26 msg_off = tmidi.Message(tmidi.NOTE_OFF, notenum, 0, channel=midi_channel - 1)
27 print("sending note off msg:", msg_off)
28 midi_usb.send(msg_off)
29 time.sleep(0.2)
Simple receiver
Show to to receive MIDI messages.
examples/tmidi_simple_receiver.py
1# SPDX-FileCopyrightText: Copyright (c) 2024 Tod Kurt
2#
3# SPDX-License-Identifier: MIT
4
5# This example shows how to receive MIDI NoteOn and NoteOff messages
6
7import usb_midi
8import tmidi
9
10midi_usb = tmidi.MIDI(midi_in=usb_midi.ports[0], midi_out=usb_midi.ports[1])
11
12while True:
13 if msg := midi_usb.receive():
14 if msg.type == tmidi.NOTE_ON and msg.velocity > 0:
15 print(
16 "note on: note:",
17 msg.note,
18 "vel:",
19 msg.velocity,
20 "channel:",
21 msg.channel,
22 )
23 elif msg.type == tmidi.NOTE_OFF or msg.velocity == 0:
24 print(
25 "note off: note:",
26 msg.note,
27 "vel:",
28 msg.velocity,
29 "channel:",
30 msg.channel,
31 )
Multiple receivers
Show to to receive MIDI messages from multiple receivers.
examples/tmidi_multiple_receiver.py
1# SPDX-FileCopyrightText: Copyright (c) 2024 Tod Kurt
2#
3# SPDX-License-Identifier: MIT
4
5# This example shows how to receive MIDI from multiple devices,
6# in this case USB MIDI and serial MIDI.
7# The serial MIDI is connected to TX/RX pins on a Feather or QTPy.
8# You must wire up the needed resistors and MIDI jack yourself,
9# or use the MIDI Feather wing.
10
11import time
12import board
13import busio
14import usb_midi
15
16import tmidi
17
18uart = busio.UART(rx=board.RX, tx=board.TX, baudrate=31250, timeout=0.001)
19midi_uart = tmidi.MIDI(midi_in=uart)
20midi_usb = tmidi.MIDI(midi_in=usb_midi.ports[0])
21
22last_time = 0
23while True:
24 if time.monotonic() - last_time > 1.0:
25 last_time = time.monotonic()
26 print("waiting for midi on either usb or uart...")
27
28 if msg := midi_usb.receive() or midi_uart.receive():
29 print("%5.2f" % time.monotonic(), msg)
Simple arpeggiator
Implement a simple arpeggiator that receives MIDI and sends it
examples/tmidi_simple_arpeggiator.py
1# SPDX-FileCopyrightText: Copyright (c) 2024 Tod Kurt
2#
3# SPDX-License-Identifier: MIT
4
5# This example shows both receiving and sending MIDI messages
6# by implementing a simple arpeggiator.
7# MIDI notes send to MIDI In are arpeggiated to MIDI Output.
8
9import time
10import usb_midi
11import tmidi
12
13midi = tmidi.MIDI(midi_in=usb_midi.ports[0], midi_out=usb_midi.ports[1])
14# if serial midi
15# uart = busio.UART(rx=board.RX, tx=board.TX, timeout=0.000)
16# midi = tmidi.MIDI(midi_in=uart, midi_out=uart)
17
18tempo = 120 # bpm
19notes_per_beat = 2 # 1 = quarter-note, 2 = 8th, 4 = 16th
20note_time = 60 / tempo / notes_per_beat
21gate_percent = 0.5
22
23pressed_notes = []
24note_i = 0
25last_note_time = 0
26gate_time = 0
27while True:
28 # handle midi input
29 if msg := midi.receive():
30 if msg.type == tmidi.NOTE_ON and msg.velocity > 0:
31 print("note on", msg)
32 pressed_notes.append(msg.note)
33 elif msg.type == tmidi.NOTE_OFF or (
34 msg.type == tmidi.NOTE_ON and msg.velocity == 0
35 ):
36 if msg.note in pressed_notes:
37 midi.send(msg) # send the note off
38 pressed_notes.remove(msg.note)
39 note_i = 0
40
41 # do midi output
42 if len(pressed_notes) == 0:
43 continue
44
45 now = time.monotonic()
46 if now - last_note_time >= note_time:
47 last_note_time = now
48 note_on = tmidi.Message(tmidi.NOTE_ON, pressed_notes[note_i], 127)
49 print("arp note_on: ", note_on)
50 midi.send(note_on)
51 gate_time = note_time * gate_percent
52
53 if gate_time > 0 and now - last_note_time >= gate_time:
54 gate_time = 0
55 note_off = tmidi.Message(tmidi.NOTE_OFF, pressed_notes[note_i], 127)
56 print("arp note_off:", note_off)
57 midi.send(note_off)
58 note_i = (note_i + 1) % len(pressed_notes)