Initial commit
This commit is contained in:
123
main.py
Normal file
123
main.py
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3.11
|
||||
import itertools
|
||||
import sys
|
||||
import time
|
||||
import rtmidi
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
G_STATUS_NAMES = {
|
||||
0x80: "NOTE_OFF",
|
||||
0x90: "NOTE_ON",
|
||||
0xa0: "KEY_PRESSR",
|
||||
0xb0: "CTRL_CHANGE",
|
||||
0xc0: "PROG_CHANGE",
|
||||
0xd0: "CHAN_PRESSR",
|
||||
0xe0: "PITCH_BEND",
|
||||
0xf0: "XXX",
|
||||
}
|
||||
|
||||
|
||||
def note_on(chan: int, note: int, velocity: int) -> Tuple[int, int, int]:
|
||||
assert 0 < chan <= 16, chan
|
||||
assert 0 <= note <= 0xFF, note
|
||||
assert 0 <= velocity <= 0xFF, velocity
|
||||
msg_byte = 0x90 + (chan - 1)
|
||||
return msg_byte, note, velocity
|
||||
|
||||
|
||||
def note_off(chan: int, note: int) -> Tuple[int, int, int]:
|
||||
assert 0 < chan <= 16, chan
|
||||
assert 0 <= note <= 0xFF, note
|
||||
msg_byte = 0x80 + (chan - 1)
|
||||
return msg_byte, note, 0
|
||||
|
||||
|
||||
def get_status_name(status: int) -> str:
|
||||
return G_STATUS_NAMES.get(status & 0xF0) or f'<? {status:02x} ?>'
|
||||
|
||||
|
||||
def test_midi_out() -> int:
|
||||
midi_out = rtmidi.MidiOut()
|
||||
ports: list[str] = midi_out.get_ports()
|
||||
print('Ports:')
|
||||
for i, port_name in enumerate(ports):
|
||||
print(f'{i:2d} {port_name}')
|
||||
|
||||
# nanokey_index: int = ([i for i, port_name in enumerate(ports) if 'nanoKEY' in port_name] or [-1])[0]
|
||||
# if nanokey_index < 0:
|
||||
# print(f'nanoKEY2 port -> NOT FOUND [{ports}]', file=sys.stderr)
|
||||
# return 1
|
||||
#
|
||||
# print(f'nanoKEY2 port -> {nanokey_index} ({ports[nanokey_index]})')
|
||||
# midi_out.open_port(nanokey_index)
|
||||
midi_out.open_port(0)
|
||||
with midi_out:
|
||||
midi_out.send_message(note_on(1, 60, 112))
|
||||
time.sleep(0.5)
|
||||
midi_out.send_message(note_off(1, 60))
|
||||
time.sleep(0.1)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def handle_midi_event(msg, midi_out):
|
||||
midi_msg, delay = msg
|
||||
status, b1, b2 = midi_msg
|
||||
b_hi = b1 + (b2 << 8)
|
||||
status_name = get_status_name(status)
|
||||
# if status_name == "PITCH_BEND":
|
||||
print(f'[d:{delay:2.2f}] {status_name:11s} [ch {1 + (status & 0x0f)}] -> {b1:02x}[{b1:3d}] {b2:02x}[{b2:3d}] hi: {b_hi}')
|
||||
|
||||
midi_out.send_message([status, b1, 127])
|
||||
|
||||
|
||||
def set_all(midi_out, value):
|
||||
for ch, btn_id in itertools.product([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16], range(128)):
|
||||
midi_out.send_message(note_on(ch, btn_id, value))
|
||||
|
||||
|
||||
def test_midi_in() -> int:
|
||||
midi_in = rtmidi.MidiIn()
|
||||
ports: list[str] = midi_in.get_ports()
|
||||
print('Ports:')
|
||||
for i, port_name in enumerate(ports):
|
||||
print(f'{i:2d} {port_name}')
|
||||
|
||||
midi_out = rtmidi.MidiOut()
|
||||
|
||||
port = 1
|
||||
midi_in.set_callback(handle_midi_event, midi_out)
|
||||
midi_in.open_port(port)
|
||||
midi_out.open_port(port)
|
||||
try:
|
||||
set_all(midi_out, 127)
|
||||
time.sleep(0.5)
|
||||
set_all(midi_out, 0)
|
||||
|
||||
i = 0
|
||||
levels = list(range(3))
|
||||
while True:
|
||||
if i >= len(levels):
|
||||
i = -len(levels) + 1
|
||||
|
||||
midi_out.send_message(note_on(3, 2, levels[abs(i)]))
|
||||
|
||||
i += 1
|
||||
time.sleep(0.5)
|
||||
except KeyboardInterrupt:
|
||||
print('CTRL+C TRIGGERED')
|
||||
finally:
|
||||
set_all(midi_out, 0)
|
||||
midi_in.cancel_callback()
|
||||
midi_in.close_port()
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def main() -> int:
|
||||
return test_midi_in()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user