https://musescore.com/user/33186954/scores/6147994
@UnsignedArduino, can you help make this music for my game? Thanks!
https://musescore.com/user/33186954/scores/6147994
@UnsignedArduino, can you help make this music for my game? Thanks!
This time it was slightly annoying because Musescore has decided to disable the playback feature.
Hey @UnsignedArduino. How exactly do you make these tracks? They sound really good and I want to try making some on my own.
.mid
).mid
file into a .json
file using the mid_to_json.py
script..json
file into a .ts
file using the json_to_ts.py
script..ts
file into an Arcade project.timers
extension.You are going to need some Python knowledge to use these scripts.
# mid_to_json.py
# Install mido with pip install mido
# PyPI page: https://pypi.org/project/mido/
from mido import MidiFile, open_output
from pathlib import Path
from json import dumps
from time import sleep
# The path to the midi file.
# vvv CHANGE THIS!!! vvv
midi_path = Path.cwd() / "midi_file.mid"
# ^^^ CHANGE THIS!!! ^^^
json_path = Path.cwd() / (midi_path.stem + ".json")
midi_file = MidiFile(str(midi_path))
json_dict = {"midi": []}
def midi_to_name(midi: int = 0):
note_names = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]
return note_names[midi % 12] + str(int(((midi / 12) - 1)))
print(f"Input midi file path is '{midi_path}'")
# port = open_output("Microsoft GS Wavetable Synth 0")
# for msg in midi_file:
# sleep(msg.time)
# if msg.type == "note_on":
# port.send(msg)
# print(msg)
# port.close()
notes = []
for msg in midi_file:
if msg.type == "note_on":
if msg.velocity == 0:
for index in range(len(notes)):
notes[index]["time"] = msg.time
if len(notes) > 0:
json_dict["midi"].append(notes)
notes = []
else:
notes.append({
"note": msg.note,
"name": midi_to_name(msg.note),
"velocity": msg.velocity,
"time": msg.time
})
# print(msg)
json_path.write_text(dumps(json_dict, indent=4))
print(f"Output json file path is '{json_path}'")
# json_to_ts.py
from pathlib import Path
from json import loads
# The path to the json file that mid_to_json exported.
# vvv CHANGE THIS!!! vvv
json_path = Path.cwd() / "json_file.json"
# ^^^ CHANGE THIS!!! ^^^
ts_path = Path.cwd() / "Quietude by Mary Sue Brock" / (json_path.stem + ".ts")
def get_frequency(note, A4=440):
notes = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#']
octave = int(note[2]) if len(note) == 3 else int(note[1])
keyNumber = notes.index(note[0:-1]);
if (keyNumber < 3) :
keyNumber = keyNumber + 12 + ((octave - 1) * 12) + 1;
else:
keyNumber = keyNumber + ((octave - 1) * 12) + 1;
return A4 * 2** ((keyNumber- 49) / 12)
print(f"Input json file path is '{json_path}'")
json_dict = loads(json_path.read_text())
ts = "function play_song() {\n"
current_velocity = None
speed_multiplier = 1
for chord in json_dict["midi"]:
block = "{indent}// [notes]\n{indent}".format(indent=" "*4)
block += "{\n"
notes_in_chord = 0
notes = []
for index, note in enumerate(chord):
notes_in_chord += 1
if notes_in_chord > 5:
continue
if note["time"] == 0:
continue
if not current_velocity == note["velocity"]:
current_velocity = note["velocity"]
block += "{indent}music.setVolume({velocity})\n".format(
indent = " " * 8, velocity = current_velocity
)
if len(chord) - 1 == index:
block += "{indent}// {note}\n".format(indent=" "*8, note=note["name"])
length = int((note["time"] * 1000) * speed_multiplier)
delay = 0
if length > 2000:
delay = length - 2000
length = 2000
block += "{indent}music.playTone({hertz}, {duration})\n".format(
indent = " " * 8,
hertz = int(get_frequency(note=note["name"])),
duration = length
)
if not delay == 0:
block += "{indent}pause({delay})\n".format(
indent = " " * 8, delay = delay
)
else:
block += "{indent}// {note}\n".format(indent=" "*8, note=note["name"])
block += "{indent}timer.background(function() ".format(indent=" "*8)
block += "{\n"
length = int(note["time"] * 1000) * speed_multiplier
delay = 0
if length > 2000:
delay = length - 2000
length = 2000
block += "{indent}music.playTone({hertz}, {duration})\n".format(
indent = " " * 12,
hertz = int(get_frequency(note=note["name"])),
duration = length
)
if not delay == 0:
block += "{indent}pause({delay})\n".format(
indent = " " * 12, delay = delay
)
block += " " * 8
block += "})\n"
notes.append(note["name"])
block = block.replace("[notes]", str(notes))
block += " " * 4
block += "}\n"
ts += block
ts += "}\n"
ts += "play_song()"
ts_path.write_text(ts)
print(f"Output ts file path is '{ts_path}'")
This is way to much for me to understand at once. Maybe @richard and the team can try showing an example, or a tool to convert audio to rtttl