A single-file reference implementation: the codec (8↔7-bit + CRC-16 + SysEx framing), command builders for every documented register, and a small CLI. No dependencies — standard library only (Python 3.8+).
Implements ../spec/SPEC.md. Verified byte-identical to the
JavaScript port.
# Decode a captured SysEx message into its fields (shows payload + whether the CRC is valid)
python3 orba_protocol.py decode F0 00 02 03 00 03 50 60 40 00 00 06 00 18 0c 1d F7
# Build a full SysEx message from a msgID + payload (correct CRC computed for you)
python3 orba_protocol.py build 60 03 01 00 03 02 # SET active part = Bass (index 2)
# Take a captured command and change one payload byte (byte index = value), re-CRC
python3 orba_protocol.py setval F0 00 ... F7 -- 4=0x05 # e.g. flip transport value to "play"import orba_protocol as O
# Command builders return a payload list; wrap it with build_command(payload, msg_id).
sysex = O.build_command(O.set_active_part("bass")) # bytes, F0 .. F7
sysex = O.build_command(O.set_tempo(120.0)) # 120.00 BPM
sysex = O.build_command(O.play()) # transport: play/resume
# Per-part mix FX (percent 0-100): volume | reverb | delay | pan
O.set_fx("bass", "volume", 50) # -> [0x03,0x02,0x50,0x10,0x80,0x00,0x01,0x04]
# Preset selection returns a list of payloads (select, then commit for parts):
for payload in O.select_preset("lead", "MyLead.artipreset"):
send(O.build_command(payload))
# Reads (GET) — send these, then decode the reply:
send(O.build_command(O.get_active_part()))
reply = O.decode_message(received_sysex) # {"payload", "crc_ok", "msgID", ...}
if reply["crc_ok"]:
info = reply["payload"] # [op, domain, addrHi, addrLo, *value]
# Decode a name reply / tempo reply:
O.ascii_name(reply["payload"][4:]) # instrument name as text
O.tempo_to_bpm(reply["payload"]) # BPM from a tempo GET replybuild_command is also available under its legacy name build_message.
This library only builds/decodes bytes — pair it with any MIDI transport:
- USB-MIDI: send the SysEx to the Orba's bidirectional "Lead" port (e.g.
amidi -p hw:X,0,0 -S '<hex>', ormidofor read/reply). - BLE-MIDI: wrap the SysEx in BLE-MIDI packets and write to the BLE-MIDI characteristic
(the JS port includes
bleWrapMidiPackets; in Python, frame per [../spec/SPEC.md§3]).