-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdecoder.py
More file actions
69 lines (51 loc) · 1.92 KB
/
decoder.py
File metadata and controls
69 lines (51 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from typing import Optional, List
from pathlib import Path
import argparse
from mido import MidiFile, MidiTrack
from mido import Message, MetaMessage
def decode_meta_message(line: str) -> MetaMessage:
args = line[12:-1].split(", ")
message_type = args.pop(0)[1:-1]
#args = [argument.split("=") for argument in args]
kwargs = {}
for argument in args:
key, value = argument.split("=")
if value.startswith("'") and value.endswith("'"): # string, we gotta remove the quotes
value = value[1:-1]
elif value.isnumeric():
value = int(value)
kwargs[key] = value
#print(f"Decoded meta message: {message_type} {kwargs}")
return MetaMessage(message_type, **kwargs)
def decode(text: List[str]) -> MidiFile:
track = MidiTrack()
for line in text:
if line.startswith("MetaMessage"):
track.append(decode_meta_message(line))
continue
try:
track.append(Message.from_str(line))
except:
print(f"Failed to decode message: {line}")
return MidiFile(tracks=[track])
def main(file_path: Path, output: Optional[Path] = None):
output = output or file_path.with_suffix(".mid")
with open(file_path, "r") as file:
text = file.read()
midi = decode(text.splitlines())
midi.save(output)
print(f"MIDI file successfully decoded from {file_path}! Saved to {output}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Decode a MIDI in a text format back to a MIDI file.")
parser.add_argument(
"file_path",
help="The path to tthe text file.",
type=Path
)
parser.add_argument(
"--output", "-o",
help="The path to the output file. Defaults to the same path as the input file, with a `.mid` file extension.",
default=None,
type=Path
)
main(**vars(parser.parse_args()))