-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add p600_recv and p600_send, rename p600_syxdump to p600_decode
- Loading branch information
Showing
11 changed files
with
337 additions
and
112 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,4 +18,4 @@ repos: | |
hooks: | ||
- id: mypy | ||
exclude: ^tests/ | ||
args: [--strict] | ||
args: [--strict, --scripts-are-modules] |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import os | ||
import sys | ||
|
||
import p600syx | ||
|
||
argparser = argparse.ArgumentParser( | ||
description="Print preset contents of Prophet-600 MIDI SysEx dumps." | ||
) | ||
argparser.add_argument( | ||
"-d", "--debug", action="store_true", help="turn on debug output" | ||
) | ||
argparser.add_argument( | ||
"-m", | ||
"--message", | ||
type=int, | ||
default=-1, | ||
help="select message number (default: all messages)", | ||
) | ||
argparser.add_argument( | ||
"-p", | ||
"--program", | ||
type=int, | ||
default=-1, | ||
help="select program number (default: all programs)", | ||
) | ||
argparser.add_argument( | ||
"infile", | ||
nargs="?", | ||
help="input sysex file. If no file is given, the script will read from standard input.", | ||
) | ||
args = argparser.parse_args() | ||
|
||
if args.infile: | ||
if not os.path.exists(args.infile): | ||
print(f"File {args.infile} not found, exiting") | ||
sys.exit(1) | ||
if args.debug: | ||
print(f"Reading from file {args.infile}", file=sys.stderr) | ||
with open(args.infile, "rb") as f: | ||
raw_data = f.read() | ||
else: | ||
if args.debug: | ||
print("Reading from stdin", file=sys.stderr) | ||
raw_data = sys.stdin.buffer.read() | ||
|
||
# Split SysEx stream at the terminating 0xf7, drop empty messages | ||
msgs = [msg for msg in raw_data.split(b"\xf7") if len(msg)] | ||
if args.debug: | ||
print(f"Found {len(msgs)} messages") | ||
|
||
for i, m in enumerate(msgs): | ||
if args.message > -1 and i != args.message: | ||
continue | ||
parser = p600syx.factory.get_parser(m) | ||
if not parser: | ||
print(f"No suitable parser found for message {i}") | ||
if args.debug: | ||
for chunk in [m[i : i + 5] for i in range(0, len(m), 5)]: | ||
for char in chunk: | ||
print(f"{char:02x}", file=sys.stderr, end="") | ||
print(" ", file=sys.stderr, end="") | ||
print(file=sys.stderr) | ||
continue | ||
if args.debug: | ||
print(f"Using {parser.name} for message {i}", file=sys.stderr) | ||
program, parameters, data = parser.decode(m) | ||
if args.program > -1 and program != args.program: | ||
continue | ||
print() | ||
print(f'{"Program number":30}: {program:5}') | ||
for name, value in parameters: | ||
if name.startswith("Patch Name") and value > 0: | ||
print(f"{name:30}: {value:5} {repr(chr(value))}") | ||
else: | ||
print(f"{name:30}: {value:5}") | ||
|
||
if args.debug: | ||
print(file=sys.stderr) | ||
print(f"Data length: {len(data)}", file=sys.stderr) | ||
print(data, file=sys.stderr) | ||
print(file=sys.stderr) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import os | ||
import sys | ||
import time | ||
|
||
import mido # type: ignore | ||
|
||
from p600syx.util import SysEx, get_config, get_port | ||
|
||
argparser = argparse.ArgumentParser( | ||
description="Receive MIDI SysEx dumps from Prophet-600." | ||
) | ||
argparser.add_argument( | ||
"-c", | ||
"--config", | ||
default=os.path.join( | ||
os.environ["HOME"], ".config", f"{argparser.prog}.conf" | ||
), | ||
help="configuration file (default: %(default)s)", | ||
) | ||
argparser.add_argument( | ||
"-d", "--debug", action="store_true", help="turn on debug output" | ||
) | ||
argparser.add_argument( | ||
"-l", "--list", action="store_true", help="list MIDI ports and exit" | ||
) | ||
argparser.add_argument( | ||
"-n", | ||
"--number", | ||
type=int, | ||
default=-1, | ||
help="select patch number (-1 for all, default: %(default)s)", | ||
) | ||
argparser.add_argument("-p", "--port", help="MIDI port that should be used") | ||
argparser.add_argument( | ||
"-s", | ||
"--sleep", | ||
type=int, | ||
default=150, | ||
help="number of milliseconds to wait between messages (default: %(default)s)", | ||
) | ||
argparser.add_argument( | ||
"outfile", | ||
nargs="?", | ||
help="output sysex file", | ||
) | ||
args = argparser.parse_args() | ||
|
||
inports = set(mido.get_input_names()) | ||
outports = set(mido.get_output_names()) | ||
if args.list: | ||
print(f"MIDI in ports: {inports}") | ||
print(f"MIDI out ports: {outports}") | ||
sys.exit(0) | ||
|
||
config = get_config(args, [args.config]) | ||
debug = config.get("debug", False) | ||
|
||
port = config.get("port", "") | ||
inport = get_port(inports, port) | ||
outport = get_port(outports, port) | ||
|
||
patch_number = int(config.get("number", -1)) | ||
if patch_number < 0: | ||
patches = range(100) | ||
else: | ||
patches = range(patch_number, patch_number + 1) | ||
|
||
if debug: | ||
print(f"Dumping {len(patches)} patches", file=sys.stderr) | ||
|
||
data = b"" | ||
with mido.open_output(outport) as midiout: | ||
with mido.open_input(inport) as midiin: | ||
for i, patch in enumerate(patches): | ||
if debug: | ||
print(f"Requesting patch {i:02}", file=sys.stderr) | ||
msg = mido.Message( | ||
"sysex", | ||
data=[ | ||
SysEx.SYSEX_ID_0, | ||
SysEx.SYSEX_ID_1, | ||
SysEx.SYSEX_ID_2, | ||
SysEx.SYSEX_COMMAND_PATCH_DUMP_REQUEST, | ||
patch, | ||
], | ||
) | ||
midiout.send(msg) | ||
|
||
reply = midiin.receive() | ||
data += bytes(reply.bytes()) | ||
time.sleep(args.sleep / 1000.0) | ||
|
||
outfile = config.get("outfile", None) | ||
if outfile: | ||
if debug: | ||
print(f"Writing to file {outfile}", file=sys.stderr) | ||
with open(outfile, "wb") as f: | ||
f.write(data) | ||
else: | ||
if debug: | ||
print(f"Using standard output", file=sys.stderr) | ||
sys.stdout.buffer.write(data) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import os | ||
import sys | ||
import time | ||
|
||
import mido # type: ignore | ||
|
||
from p600syx.util import get_config, get_port | ||
|
||
argparser = argparse.ArgumentParser( | ||
description="Send MIDI SysEx dumps to Prophet-600." | ||
) | ||
argparser.add_argument( | ||
"-c", | ||
"--config", | ||
default=os.path.join( | ||
os.environ["HOME"], ".config", f"{argparser.prog}.conf" | ||
), | ||
help="configuration file (default: %(default)s)", | ||
) | ||
argparser.add_argument( | ||
"-d", "--debug", action="store_true", help="turn on debug output" | ||
) | ||
argparser.add_argument( | ||
"-l", "--list", action="store_true", help="list MIDI ports and exit" | ||
) | ||
argparser.add_argument("-p", "--port", help="MIDI port that should be used") | ||
argparser.add_argument( | ||
"-s", | ||
"--sleep", | ||
type=int, | ||
default=150, | ||
help="number of milliseconds to wait between messages (default: %(default)s)", | ||
) | ||
argparser.add_argument( | ||
"infile", | ||
nargs="?", | ||
help="input sysex file", | ||
) | ||
args = argparser.parse_args() | ||
|
||
outs = set(mido.get_output_names()) | ||
if args.list: | ||
print(f"MIDI ports: {outs}") | ||
sys.exit(0) | ||
|
||
config = get_config(args, [args.config]) | ||
debug = config.get("debug", False) | ||
|
||
port = config.get("port", "") | ||
outport = get_port(outs, port) | ||
|
||
infile = config.get("infile", None) | ||
if not infile: | ||
print(f"Requiring input file, exiting") | ||
sys.exit(1) | ||
if not os.path.exists(infile): | ||
print(f"File {infile} not found, exiting") | ||
sys.exit(1) | ||
if debug: | ||
print(f"Reading from file {infile}", file=sys.stderr) | ||
messages = mido.read_syx_file(infile) | ||
if debug: | ||
print(f"Read {len(messages)} from file, sending now", file=sys.stderr) | ||
|
||
with mido.open_output(outport) as o: | ||
for i, m in enumerate(messages): | ||
if debug: | ||
print(f"Sending message {i+1}", file=sys.stderr) | ||
o.send(m) | ||
time.sleep(args.sleep / 1000.0) |
Oops, something went wrong.