|
8 | 8 | """ |
9 | 9 | import pylibremidi as lm |
10 | 10 |
|
11 | | -# --- MIDI 1 Raw I/O --- |
12 | | -print("=== MIDI 1 Raw I/O ===") |
13 | 11 |
|
14 | | -# The library will give us a callback to call when bytes arrive |
15 | | -stored_cb = None |
| 12 | +def midi1_example(): |
| 13 | + print("=== MIDI 1 Raw I/O ===") |
16 | 14 |
|
17 | | -# Input: receive and print parsed MIDI messages |
18 | | -in_config = lm.InputConfiguration() |
19 | | -in_config.on_message = lambda msg: print(f" Received: {msg}") |
20 | | -in_config.direct = True # Call Python callbacks directly (no poll needed) |
| 15 | + # The library will give us a callback to call when bytes arrive |
| 16 | + stored_cb = [None] |
21 | 17 |
|
22 | | -rawio_in = lm.RawioInputConfiguration() |
23 | | -rawio_in.set_receive_callback = lambda cb: globals().update(stored_cb=cb) |
24 | | -rawio_in.stop_receive = lambda: globals().update(stored_cb=None) |
| 18 | + # Input: receive and print parsed MIDI messages |
| 19 | + in_config = lm.InputConfiguration() |
| 20 | + in_config.on_message = lambda msg: print(f" Received: {msg}") |
| 21 | + in_config.direct = True # Call Python callbacks directly (no poll needed) |
25 | 22 |
|
26 | | -midi_in = lm.MidiIn(in_config, rawio_in) |
27 | | -midi_in.open_virtual_port("rawio_in") |
| 23 | + rawio_in = lm.RawioInputConfiguration() |
| 24 | + rawio_in.set_receive_callback = lambda cb: stored_cb.__setitem__(0, cb) |
| 25 | + rawio_in.stop_receive = lambda: stored_cb.__setitem__(0, None) |
28 | 26 |
|
29 | | -# Output: loopback written bytes into the input |
30 | | -out_config = lm.OutputConfiguration() |
| 27 | + midi_in = lm.MidiIn(in_config, rawio_in) |
| 28 | + midi_in.open_virtual_port("rawio_in") |
31 | 29 |
|
32 | | -def loopback_write(data): |
33 | | - if stored_cb: |
34 | | - stored_cb(data, 0) |
35 | | - return lm.Error() |
| 30 | + # Output: loopback written bytes into the input |
| 31 | + out_config = lm.OutputConfiguration() |
36 | 32 |
|
37 | | -rawio_out = lm.RawioOutputConfiguration() |
38 | | -rawio_out.write_bytes = loopback_write |
| 33 | + def loopback_write(data): |
| 34 | + if stored_cb[0]: |
| 35 | + stored_cb[0](data, 0) |
| 36 | + return lm.Error() |
39 | 37 |
|
40 | | -midi_out = lm.MidiOut(out_config, rawio_out) |
41 | | -midi_out.open_virtual_port("rawio_out") |
| 38 | + rawio_out = lm.RawioOutputConfiguration() |
| 39 | + rawio_out.write_bytes = loopback_write |
42 | 40 |
|
43 | | -# Send some MIDI messages - they loop back through the rawio transport |
44 | | -print("Sending Note On C4...") |
45 | | -midi_out.send_message(0x90, 60, 100) |
| 41 | + midi_out = lm.MidiOut(out_config, rawio_out) |
| 42 | + midi_out.open_virtual_port("rawio_out") |
46 | 43 |
|
47 | | -print("Sending Note Off C4...") |
48 | | -midi_out.send_message(0x80, 60, 0) |
| 44 | + # Send some MIDI messages - they loop back through the rawio transport |
| 45 | + print("Sending Note On C4...") |
| 46 | + midi_out.send_message(0x90, 60, 100) |
49 | 47 |
|
50 | | -print("Sending CC Volume=80...") |
51 | | -midi_out.send_message(0xB0, 7, 80) |
| 48 | + print("Sending Note Off C4...") |
| 49 | + midi_out.send_message(0x80, 60, 0) |
52 | 50 |
|
53 | | -# --- MIDI 2 Raw I/O (UMP) --- |
54 | | -print("\n=== MIDI 2 Raw I/O (UMP) ===") |
| 51 | + print("Sending CC Volume=80...") |
| 52 | + midi_out.send_message(0xB0, 7, 80) |
55 | 53 |
|
56 | | -stored_ump_cb = None |
| 54 | + # close_port breaks the reference cycle: midi_out -> write -> stored_cb -> C++ callback -> midi_in |
| 55 | + midi_in.close_port() |
| 56 | + midi_out.close_port() |
57 | 57 |
|
58 | | -ump_in_config = lm.UmpInputConfiguration() |
59 | | -ump_in_config.on_message = lambda msg: print(f" Received UMP: {msg}") |
60 | | -ump_in_config.direct = True |
61 | 58 |
|
62 | | -rawio_ump_in = lm.RawioUmpInputConfiguration() |
63 | | -rawio_ump_in.set_receive_callback = lambda cb: globals().update(stored_ump_cb=cb) |
64 | | -rawio_ump_in.stop_receive = lambda: globals().update(stored_ump_cb=None) |
| 59 | +def midi2_example(): |
| 60 | + print("\n=== MIDI 2 Raw I/O (UMP) ===") |
65 | 61 |
|
66 | | -ump_midi_in = lm.MidiIn(ump_in_config, rawio_ump_in) |
67 | | -ump_midi_in.open_virtual_port("rawio_ump_in") |
| 62 | + stored_cb = [None] |
68 | 63 |
|
69 | | -ump_out_config = lm.OutputConfiguration() |
| 64 | + ump_in_config = lm.UmpInputConfiguration() |
| 65 | + ump_in_config.on_message = lambda msg: print(f" Received UMP: {msg}") |
| 66 | + ump_in_config.direct = True |
70 | 67 |
|
71 | | -def loopback_write_ump(data): |
72 | | - if stored_ump_cb: |
73 | | - stored_ump_cb(data, 0) |
74 | | - return lm.Error() |
| 68 | + rawio_ump_in = lm.RawioUmpInputConfiguration() |
| 69 | + rawio_ump_in.set_receive_callback = lambda cb: stored_cb.__setitem__(0, cb) |
| 70 | + rawio_ump_in.stop_receive = lambda: stored_cb.__setitem__(0, None) |
75 | 71 |
|
76 | | -rawio_ump_out = lm.RawioUmpOutputConfiguration() |
77 | | -rawio_ump_out.write_ump = loopback_write_ump |
| 72 | + midi_in = lm.MidiIn(ump_in_config, rawio_ump_in) |
| 73 | + midi_in.open_virtual_port("rawio_ump_in") |
78 | 74 |
|
79 | | -ump_midi_out = lm.MidiOut(ump_out_config, rawio_ump_out) |
80 | | -ump_midi_out.open_virtual_port("rawio_ump_out") |
| 75 | + ump_out_config = lm.OutputConfiguration() |
81 | 76 |
|
82 | | -# Send a MIDI 2.0 Note On UMP (group 0, channel 0, note 60) |
83 | | -print("Sending UMP Note On...") |
84 | | -ump_midi_out.send_ump(0x4090003C, 0xC0000000) |
| 77 | + def loopback_write_ump(data): |
| 78 | + if stored_cb[0]: |
| 79 | + stored_cb[0](data, 0) |
| 80 | + return lm.Error() |
85 | 81 |
|
| 82 | + rawio_ump_out = lm.RawioUmpOutputConfiguration() |
| 83 | + rawio_ump_out.write_ump = loopback_write_ump |
| 84 | + |
| 85 | + midi_out = lm.MidiOut(ump_out_config, rawio_ump_out) |
| 86 | + midi_out.open_virtual_port("rawio_ump_out") |
| 87 | + |
| 88 | + # Send a MIDI 2.0 Note On UMP (group 0, channel 0, note 60) |
| 89 | + print("Sending UMP Note On...") |
| 90 | + midi_out.send_ump(0x4090003C, 0xC0000000) |
| 91 | + |
| 92 | + midi_in.close_port() |
| 93 | + midi_out.close_port() |
| 94 | + |
| 95 | + |
| 96 | +midi1_example() |
| 97 | +midi2_example() |
86 | 98 | print("\nDone.") |
0 commit comments