Created
March 29, 2025 06:24
-
-
Save pansapiens/475972936a945621915e8b7be975c792 to your computer and use it in GitHub Desktop.
Change the Behringer 2600 pitch bend range with sysex
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# /// script | |
# requires-python = ">=3.11" | |
# dependencies = [ | |
# "mido", | |
# "python-rtmidi", | |
# ] | |
# /// | |
import mido | |
import argparse | |
import sys | |
# Subcommand to list available MIDI devices | |
def list_devices(): | |
print("Available MIDI output devices:") | |
for i, name in enumerate(mido.get_output_names()): | |
print(f"{i}: {name}") | |
# Function to send the SysEx message | |
def send_sysex(bend_range, midi_device, midi_channel=None): | |
# Construct the SysEx message (excluding F0 and F7) | |
sysex_message = [0x00, 0x20, 0x32, 0x00, 0x01, 0x0B, 0x7F, 0x11, bend_range, 0x00] | |
# Ensure all values are within the valid range (0–127) | |
for i, value in enumerate(sysex_message): | |
if not (0 <= value <= 127): | |
print(f"Error: Invalid value {value} at position {i} in SysEx message.") | |
return | |
# Open the selected MIDI device | |
try: | |
with mido.open_output(midi_device) as port: | |
# If a specific MIDI channel is provided, send only to that channel | |
if midi_channel is not None: | |
sysex_message[6] = midi_channel - 1 # MIDI channels are 0-based in SysEx | |
port.send(mido.Message('sysex', data=sysex_message)) | |
print(f"Sent SysEx message to MIDI channel {midi_channel} on device '{midi_device}'.") | |
else: | |
# Broadcast to all channels | |
for channel in range(16): | |
sysex_message[6] = channel | |
port.send(mido.Message('sysex', data=sysex_message)) | |
print(f"Broadcast SysEx message to all channels on device '{midi_device}'.") | |
except Exception as e: | |
print(f"Error sending SysEx message: {e}") | |
# Main function to parse arguments | |
def main(): | |
parser = argparse.ArgumentParser(description="Send a SysEx message with adjustable bend range.") | |
subparsers = parser.add_subparsers(dest="command") | |
# Subcommand to list MIDI devices | |
list_parser = subparsers.add_parser("list", help="List available MIDI devices.") | |
# Subcommand to send SysEx | |
send_parser = subparsers.add_parser("send", help="Send the SysEx message.") | |
send_parser.add_argument("--bend-range", type=lambda x: int(x, 16), default=0x0C, | |
help="Set the bend range (00-0C in hex), default is 0C for 12 semitones") | |
send_parser.add_argument("--midi-device", type=int, required=True, | |
help="MIDI device index (use 'list' command to see available devices).") | |
send_parser.add_argument("--midi-channel", type=int, choices=range(1, 17), | |
help="Optionally specify a MIDI channel (1-16). Broadcasts to all channels by default.") | |
args = parser.parse_args() | |
if args.command == "list": | |
list_devices() | |
elif args.command == "send": | |
# Validate bend range | |
if not (0x00 <= args.bend_range <= 0x0C): | |
print("Error: Bend range must be between 00 and 0C (hex).") | |
sys.exit(1) | |
# Get the MIDI device name from the index | |
try: | |
midi_device_name = mido.get_output_names()[args.midi_device] | |
except IndexError: | |
print(f"Error: Invalid MIDI device index '{args.midi_device}'.") | |
sys.exit(1) | |
# Send the SysEx message | |
send_sysex(args.bend_range, midi_device_name, args.midi_channel) | |
else: | |
parser.print_help() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment