Skip to content

Instantly share code, notes, and snippets.

@Sakimotor
Last active August 14, 2022 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sakimotor/623c1fcd8470c208347300382b32cda3 to your computer and use it in GitHub Desktop.
Save Sakimotor/623c1fcd8470c208347300382b32cda3 to your computer and use it in GitHub Desktop.
Technictix .mus file rearranging and converting script
#Simple python script that implements almendaz's algorithm from https://hcs64.com/mboard/forum.php?showthread=60921&showpage=2
#Requires pydub
import sys
import io
import os
from pydub import AudioSegment
#User args
argc = len(sys.argv)
if argc < 2:
exit("Usage : " + sys.argv[0] + " filename.mus [channels]")
channels = int(sys.argv[2]) if (argc == 3) else 2
#Opening the .mus file
file = open(sys.argv[1], 'rb')
filesize = os.stat(sys.argv[1]).st_size
#See https://hcs64.com/mboard/forum.php?showthread=60921&showpage=2 and https://hcs64.com/mboard/forum.php?showthread=54118&showpage=0#post_54235
size = 0x2EE00
filler = 0x200
interleave = 0x17700
offset = (size + filler) * (channels / 2)
chan1 = open('chan1.mus', 'wb')
chan2 = open('chan2.mus', 'wb')
chan3 = -1
chan4 = -1
if channels == 4:
chan3 = open('chan3.mus', 'wb')
chan4 = open('chan4.mus', 'wb')
print("filesize : " + str(filesize))
chunks = int(filesize // offset)
print(str(chunks) + " chunks")
lim_l = 0
lim_r = 0
if chunks%2 ==0:
lim_l = chunks - 2
lim_r = chunks - 1
else:
lim_l = chunks - 1
lim_r = chunks - 2
i = 0
#First we read the odd chunks (chunk 1, chunk 3, chunk 5...)
while i <= lim_l:
print("i: " + str(i))
print( str(file.tell()) + '-', end='')
out_l = file.read(interleave)
chan1.write(out_l)
out_r = file.read(interleave)
chan2.write(out_r)
if channels == 4:
#Don't forget to take in account the 0x200 space of void
file.read(filler)
out_l = file.read(interleave)
chan3.write(out_l)
out_r = file.read(interleave)
chan4.write(out_r)
file.read(filler)
print(str(file.tell()))
i += 2
if i <= lim_l:
file.seek(int(offset), 1)
i = lim_r
#Then we read the even chunks (chunk 2, chunk 4, chunk 6...) by going in the reverse order (16 -> 14 -> 12...)
while i >= 1:
print("i: " + str(i))
print( str(file.tell()) + '-', end='')
out_l = file.read(interleave)
chan1.write(out_l)
out_r = file.read(interleave)
chan2.write(out_r)
if channels == 4:
file.read(filler)
out_l = file.read(interleave)
chan3.write(out_l)
out_r = file.read(interleave)
chan4.write(out_r)
file.read(filler)
print(str(file.tell()))
i -= 2
#go backwards by the block we just read AND the ones we already handled
if i >=1:
file.seek(int(-offset*3), 1)
#Merging the channels together
one = AudioSegment.from_file("chan1.mus", format='raw', frame_rate=24000, channels=1, sample_width=2)
two = AudioSegment.from_file("chan2.mus", format='raw', frame_rate=24000, channels=1, sample_width=2)
if channels == 2:
res = AudioSegment.from_mono_audiosegments(one, two).export( sys.argv[1] + '.wav', format='wav')
if channels == 4:
three = AudioSegment.from_file("chan3.mus", format='raw', frame_rate=24000, channels=1, sample_width=2)
four = AudioSegment.from_file("chan4.mus", format='raw', frame_rate=24000, channels=1, sample_width=2)
res = AudioSegment.from_mono_audiosegments(one, two, three, four).export( sys.argv[1] + '.wav', format='wav')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment