|
|
@@ -8,7 +8,7 @@ def Error(*args): |
|
|
|
if len(sys.argv) > 1: |
|
|
|
Filename = sys.argv[1] |
|
|
|
|
|
|
|
Options, Args = getopt.getopt(sys.argv[1:], "ot:") |
|
|
|
Options, Args = getopt.getopt(sys.argv[1:], "bot:") |
|
|
|
|
|
|
|
def OptionExist(opt): |
|
|
|
global Options |
|
|
@@ -24,22 +24,50 @@ def GetOption(opt): |
|
|
|
if len(Args) >= 1: |
|
|
|
Filename = Args[0] |
|
|
|
else: |
|
|
|
Error("need a file, genius") |
|
|
|
Error("no input file") |
|
|
|
|
|
|
|
|
|
|
|
DataFile = open(Filename,"r") |
|
|
|
BinMode = OptionExist("-b") |
|
|
|
DataFile = open(Filename,"r" + ("b" if BinMode else "")) if Filename != "-" else sys.stdin |
|
|
|
# MiOPMdrv sound bank Paramer Ver2002.04.22 |
|
|
|
# LFO: LFRQ AMD PMD WF NFRQ |
|
|
|
# @:[Num] [Name] |
|
|
|
# CH: PAN FL CON AMS PMS SLOT NE |
|
|
|
# [OPname]: AR D1R D2R RR D1L TL KS MUL DT1 DT2 AMS-EN |
|
|
|
Data = [] |
|
|
|
Data = [] if not BinMode else DataFile.read() |
|
|
|
OpNames = ["M1","C1","M2","C2"] |
|
|
|
OpIdx = [0,2,1,3] |
|
|
|
|
|
|
|
for line in DataFile.readlines(): |
|
|
|
for byte in line.strip().split(",")[:16]: |
|
|
|
Data.append(int(byte,16)) |
|
|
|
if not BinMode: |
|
|
|
for line in DataFile.readlines(): |
|
|
|
for byte in line.strip().split(",")[:16]: |
|
|
|
Data.append(int(byte,16)) |
|
|
|
|
|
|
|
def PrintChannel(pan, fl, con, ams, pms, slot, ne): |
|
|
|
print("CH:", pan, fl, con, ams, pms, slot, ne) |
|
|
|
|
|
|
|
def PrintOp(op, ar, d1r, d2r, rr, d1l, tl, ks, mul, dt1, dt2, amsen): |
|
|
|
print(OpNames[op] + ":", ar, d1r, d2r, rr, d1l, tl, ks, mul, dt1, dt2, amsen) |
|
|
|
|
|
|
|
def GetFlCon(b): |
|
|
|
return (b & 0b00111000) >> 3, (b & 0b00000111) |
|
|
|
|
|
|
|
def GetAMSPMS(b): |
|
|
|
return (b & 0b00110000) >> 4, (b & 0b00000111) |
|
|
|
|
|
|
|
def GetDT1Mul(b): |
|
|
|
return (b & 0b01110000) >> 4, (b & 0b00001111) |
|
|
|
|
|
|
|
def GetKSAR(b): |
|
|
|
return (b & 0b11000000) >> 6, (b & 0b00011111) |
|
|
|
|
|
|
|
def GetAmsenD1R(b): |
|
|
|
return (b & 0b10000000) >> 7, (b & 0b00011111) |
|
|
|
|
|
|
|
def GetDT2D2R(b): |
|
|
|
return (b & 0b11000000) >> 6, (b & 0b00011111) |
|
|
|
|
|
|
|
def GetD1LRR(b): |
|
|
|
return (b & 0b11110000) >> 4, (b & 0b00001111) |
|
|
|
|
|
|
|
def PrintOPM(data): |
|
|
|
ne = (data[0xf] & 0b10000000) >> 7 |
|
|
@@ -52,97 +80,96 @@ def PrintOPM(data): |
|
|
|
|
|
|
|
meta = data[0x20 + i : 0x3f + i : 8] |
|
|
|
|
|
|
|
fl = (meta[0] & 0b00111000) >> 3 |
|
|
|
con = (meta[0] & 0b00000111) |
|
|
|
fl, con = GetFlCon(meta[0]) |
|
|
|
|
|
|
|
pms = (meta[3] & 0b01110000) >> 4 |
|
|
|
ams = (meta[3] & 0b00000011) |
|
|
|
pms, ams = GetAMSPMS(meta[3]) |
|
|
|
|
|
|
|
print("CH:", pan, fl, con, ams, pms, slot, ne) |
|
|
|
PrintChannel(pan, fl, con, ams, pms, slot, ne) |
|
|
|
|
|
|
|
for op in range(4): |
|
|
|
get = lambda x: data[x + i + OpIdx[op]*8] |
|
|
|
|
|
|
|
b = get(0x40) |
|
|
|
dt1 = (b & 0b01110000) >> 4 |
|
|
|
mul = (b & 0b00001111) |
|
|
|
|
|
|
|
dt1, mul = GetDT1Mul(get(0x40)) |
|
|
|
tl = get(0x60) |
|
|
|
|
|
|
|
b = get(0x80) |
|
|
|
ks = (b & 0b11000000) >> 6 |
|
|
|
ar = (b & 0b00011111) |
|
|
|
|
|
|
|
b = get(0xa0) |
|
|
|
amsen = (b & 0b10000000) >> 7 |
|
|
|
d1r = (b & 0b00011111) |
|
|
|
|
|
|
|
b = get(0xc0) |
|
|
|
dt2 = (b & 0b11000000) >> 6 |
|
|
|
d2r = (b & 0b00011111) |
|
|
|
|
|
|
|
b = get(0xe0) |
|
|
|
d1l = (b & 0b11110000) >> 4 |
|
|
|
rr = (b & 0b00001111) |
|
|
|
|
|
|
|
print(OpNames[op] + ":", ar, d1r, d2r, rr, d1l, tl, ks, mul, dt1, dt2, amsen) |
|
|
|
ks, ar = GetKSAR(get(0x80)) |
|
|
|
amsen, d1r = GetAmsenD1R(get(0xa0)) |
|
|
|
dt2, d2r = GetDT2D2R(get(0xc0)) |
|
|
|
d1l, rr = GetD1LRR(get(0xe0)) |
|
|
|
|
|
|
|
PrintOp(op, ar, d1r, d2r, rr, d1l, tl, ks, mul, dt1, dt2, amsen) |
|
|
|
|
|
|
|
print() |
|
|
|
|
|
|
|
def PrintOPN(data): |
|
|
|
def PrintOPNBasic(data, opna = False): |
|
|
|
slot = 120 |
|
|
|
pan = 64 |
|
|
|
ne = 0 # either i'm blind or opn has no noise enable bit (not that i care either way) |
|
|
|
# SR in opn parlance is equivalent to D2R in opm, thanks yamaha |
|
|
|
# likewise, SL -> D1L and DR -> D1R |
|
|
|
ofs = 0x100 if opna else 0 |
|
|
|
for i in range(3): |
|
|
|
print("@:%d Ins%d" % (i, i)) |
|
|
|
n = i + (3 if opna else 0) |
|
|
|
print("@:%d Ins%d" % (n, n)) |
|
|
|
print("LFO: 0 0 0 0 0") # no way to get this data... at least for now |
|
|
|
|
|
|
|
fbcon = data[0xb0 + i] |
|
|
|
fl = (fbcon & 0b00111000) >> 3 |
|
|
|
con = (fbcon & 0b00000111) |
|
|
|
fl, con = GetFlCon(data[ofs + 0xb0 + i]) |
|
|
|
|
|
|
|
sens = data[0xb4 + i] |
|
|
|
ams = (sens & 0b00110000) >> 4 |
|
|
|
pms = (sens & 0b00000111) |
|
|
|
ams, pms = GetAMSPMS(data[ofs + 0xb4 + i]) |
|
|
|
|
|
|
|
print("CH:", pan, fl, con, ams, pms, slot, ne) |
|
|
|
PrintChannel(pan, fl, con, ams, pms, slot, ne) |
|
|
|
|
|
|
|
for op in range(4): |
|
|
|
get = lambda x: data[x + i + OpIdx[op]*4] |
|
|
|
|
|
|
|
b = get(0x30) |
|
|
|
dt1 = (b & 0b01110000) >> 4 |
|
|
|
mul = (b & 0b00001111) |
|
|
|
get = lambda x: data[ofs + x + i + OpIdx[op]*4] |
|
|
|
|
|
|
|
dt1, mul = GetDT1Mul(get(0x30)) |
|
|
|
tl = get(0x40) |
|
|
|
ks, ar = GetKSAR(get(0x50)) |
|
|
|
amsen, d1r = GetAmsenD1R(get(0x60)) |
|
|
|
dt2, d2r = GetDT2D2R(get(0x70)) |
|
|
|
d1l, rr = GetD1LRR(get(0x80)) |
|
|
|
|
|
|
|
b = get(0x50) |
|
|
|
ks = (b & 0b11000000) >> 6 |
|
|
|
ar = (b & 0b00011111) |
|
|
|
|
|
|
|
b = get(0x60) |
|
|
|
amsen = (b & 0b10000000) >> 7 |
|
|
|
d1r = (b & 0b00011111) |
|
|
|
|
|
|
|
b = get(0x70) |
|
|
|
dt2 = (b & 0b11000000) >> 6 |
|
|
|
d2r = (b & 0b00011111) |
|
|
|
|
|
|
|
b = get(0x80) |
|
|
|
d1l = (b & 0b11110000) >> 4 |
|
|
|
rr = (b & 0b00001111) |
|
|
|
|
|
|
|
print(OpNames[op] + ":", ar, d1r, d2r, rr, d1l, tl, ks, mul, dt1, dt2, amsen) |
|
|
|
|
|
|
|
PrintOp(op, ar, d1r, d2r, rr, d1l, tl, ks, mul, dt1, dt2, amsen) |
|
|
|
|
|
|
|
def PrintOPN(data): |
|
|
|
PrintOPNBasic(data) |
|
|
|
|
|
|
|
def PrintOPNA(data): |
|
|
|
PrintOPNBasic(data) |
|
|
|
PrintOPNBasic(data, True) |
|
|
|
|
|
|
|
def PrintRaw(data): |
|
|
|
slot = 120 |
|
|
|
pan = 64 |
|
|
|
ne = 0 |
|
|
|
for n in range(0, len(data) // 32): |
|
|
|
ofs = n * 32 |
|
|
|
print("@:%d Ins%d" % (n, n)) |
|
|
|
print("LFO: 0 0 0 0 0") # no way to get this data... at least for now |
|
|
|
|
|
|
|
fl, con = GetFlCon(data[ofs+0x18]) |
|
|
|
ams, pms = GetAMSPMS(data[ofs+0x19]) |
|
|
|
|
|
|
|
PrintChannel(pan, fl, con, ams, pms, slot, ne) |
|
|
|
|
|
|
|
for op in range(4): |
|
|
|
get = lambda x: data[ofs + x + OpIdx[op]] |
|
|
|
dt1, mul = GetDT1Mul(get(0x00)) |
|
|
|
tl = get(0x04) |
|
|
|
ks, ar = GetKSAR(get(0x08)) |
|
|
|
amsen, d1r = GetAmsenD1R(get(0x0C)) |
|
|
|
dt2, d2r = GetDT2D2R(get(0x10)) |
|
|
|
d1l, rr = GetD1LRR(get(0x14)) |
|
|
|
|
|
|
|
PrintOp(op, ar, d1r, d2r, rr, d1l, tl, ks, mul, dt1, dt2, amsen) |
|
|
|
|
|
|
|
TypeFuncs = { |
|
|
|
"opn": PrintOPN, |
|
|
|
"opna": PrintOPN, # fm portion of opn and opna are functionally equivalent |
|
|
|
"opm": PrintOPM |
|
|
|
"opna": PrintOPNA, |
|
|
|
"opm": PrintOPM, |
|
|
|
"raw": PrintRaw |
|
|
|
} |
|
|
|
|
|
|
|
Type = GetOption("-t").lower() |
|
|
|
Type = GetOption("-t") |
|
|
|
if Type==None: |
|
|
|
Error("no chip type specified") |
|
|
|
if Type not in TypeFuncs: |
|
|
@@ -150,4 +177,4 @@ if Type not in TypeFuncs: |
|
|
|
|
|
|
|
print("// Exported by hootvopm : https://gitlab.com/whutt/hootvopm") |
|
|
|
print("// Chip type:",Type) |
|
|
|
TypeFuncs[Type](Data) |
|
|
|
TypeFuncs[Type.lower()](Data) |