update sbkparser to used namedtuple

This commit is contained in:
2021-03-06 14:52:37 -06:00
parent 4dec8018fd
commit 1901d48bdc
2 changed files with 86 additions and 95 deletions
+2
View File
@@ -3,3 +3,5 @@ JAK2/
JAK3/ JAK3/
OUT/ OUT/
*.mid *.mid
*.bin
*.bak
+83 -94
View File
@@ -2,6 +2,8 @@
import os import os
import argparse import argparse
import struct import struct
from collections import namedtuple
def is_valid_file(parser, arg): def is_valid_file(parser, arg):
if not os.path.exists(arg): if not os.path.exists(arg):
parser.error("The file %s does not exist!" % arg) parser.error("The file %s does not exist!" % arg)
@@ -23,127 +25,114 @@ name_length = 20
sounds_start = 24 sounds_start = 24
sounds_length = 20 sounds_length = 20
with open(args.filepath, "rb") as f: #struct type 20s I
sbkInfo = struct.unpack("20sI",f.read(24)) SBK = namedtuple('SBK','name soundCount')
print(sbkInfo) SBKStructString = "20sI"
soundDatas = []
for i in range(sbkInfo[1]):
soundData = struct.unpack("16sHH",f.read(20))
print(soundData)
f.seek(2048)
''' #struct type 16s I I
seq Sound = namedtuple('Sound','name soundDataOffset soundDataSize')
I version SoundStructString = "16sHH"
I subversion
I minorversion #struct type I I I I I I
I something? SEQ = namedtuple('SEQ','version subversion minorversion something soundBankOffset soundBankSize')
I soundbankStart SEQStructString = "6I"
I soundBankSize
''' #struct type 4s I I I I H H H H I I I I I
SB1K = namedtuple('SB1K','signature version subversion minorversion zero e f g h instrumentOffset regionOffset k l m')
SB1kStructString = "4sIIIIHHHHIIIII"
#struct type I h h h h
Instrument = namedtuple('Instrument','volume a b regionOffset d')
InstrumentStructString = 'IHHHH'
Region = namedtuple('Region','version subversion a volume b c d e1 e2 f1 f2 g1 sampleId zeros1 zeros2 zero3')
RegionStructString = 'IIBBBBIHHHHHHIII'
with open(args.filepath, "rb") as f:
sbkInstance = SBK._make(struct.unpack(SBKStructString,f.read(24)))
print(sbkInstance)
soundDatas = []
for i in range(sbkInstance.soundCount):
soundData = Sound._make(struct.unpack(SoundStructString,f.read(20)))
print(soundData)
# a ton of zeros
while(struct.unpack("B",f.read(1))[0] == 0):
continue
# found something rewind a byte
f.seek(-1,1)
seqStart = f.tell() seqStart = f.tell()
seq = struct.unpack("6I",f.read(24)) seqInstance = SEQ._make(struct.unpack(SEQStructString,f.read(24)))
print(seq) print(seqInstance)
soundbankStart = seq[4] + seqStart soundbankStart = seqInstance.soundBankOffset + seqStart
print(f"SoundBank Offset: {soundbankStart}") print(f"SoundBank Offset: {soundbankStart}")
'''
sb1k
4s signature 'SB1k'
I
I
4s
I
H
H
H
H
I instrumentOffset from beingging of this struct
I regionOffset from beginning of this struct
I
I
I
I
I
12s
H
H
H
H
I
'''
soundBankHeaderStart = f.tell() soundBankHeaderStart = f.tell()
sb1k = struct.unpack("4sII4sIHHHHIIIIIII12sHHHHI",f.read(80)) SB1KInstance = SB1K._make(struct.unpack(SB1kStructString,f.read(48)))
print(SB1KInstance)
# there is some data here
instrumentStart = SB1KInstance[8] + soundBankHeaderStart
regionStart = SB1KInstance[10] + soundBankHeaderStart
instrumentStart = sb1k[8] + soundBankHeaderStart
print(instrumentStart)
f.seek(instrumentStart) f.seek(instrumentStart)
regionStart = sb1k[10] + soundBankHeaderStart
print(sb1k)
instruments = [] instruments = []
while(f.tell() < regionStart): while(f.tell() < regionStart):
'''
struct Instrument { instrumentInstance = Instrument._make(struct.unpack(InstrumentStructString,f.read(12)))
uint8_t nRegion; // usually 1 instruments.append(instrumentInstance)
uint8_t volume; // ? maybe... like 7f is 1.0?
uint16_t something; // always 0
uint32_t oRegion; // relative to start of SBv2 block I think, points to the first region for instrument
} __attribute__((packed));
'''
instrument = struct.unpack("BBBBHI",f.read(12))
instruments.append(instrument)
print("INSTRUMENTS") print("INSTRUMENTS")
offsets = [] offsets = []
for instrument in instruments: for inst in instruments:
if instrument[-1] not in offsets: if inst.regionOffset not in offsets:
offsets.append(instrument[-1]) offsets.append(inst.regionOffset)
print(instrument) print(inst)
print(len(offsets)) print(len(instruments))
f.seek(regionStart) f.seek(regionStart)
regions = [] regions = []
while(f.tell()<soundbankStart): while(f.tell()<soundbankStart):
#format defintely not right but #format defintely not right but
region = struct.unpack("10I", f.read(40)) regionInstance = Region._make(struct.unpack(RegionStructString, f.read(40)))
regions.append(region) regions.append(regionInstance)
print("REGIONS") print("REGIONS")
sampleOffsets = [] sampleOffsets = []
for region in regions: for reg in regions:
print(region) print(reg)
sampleOffset = soundbankStart + region[-4] sampleOffset = soundbankStart + reg[-4]
if sampleOffset not in sampleOffsets: if sampleOffset not in sampleOffsets:
sampleOffsets.append(sampleOffset) sampleOffsets.append(sampleOffset)
#print(f"Region Sample Audio offset: {soundbankStart + region[10]}") #print(f"Region Sample Audio offset: {soundbankStart + region[10]}")
# this should align the index of the sample offset with it's sample ID # this should align the index of the sample offset with it's sample ID
sampleOffsets.sort() # sampleOffsets.sort()
count = 0 # count = 0
for offset in sampleOffsets: # previousOffset = 0
f.seek(offset) # for offset in sampleOffsets:
soundData = f.read(1) # previousOffset = offset
while(f.tell() not in sampleOffsets): # f.seek(offset)
character = f.read(1) # soundData = f.read(1)
if not character: # count += 1
break # while(f.tell() not in sampleOffsets):
soundData += character # character = f.read(1)
# if not character:
# break
# soundData += character
# #VAGp header data length and sample rate are packed in bytes 11-15 and 16-20 respectively
# header = b'\x56\x41\x47\x70\x00\x00\x00\x20\x00\x00\x00\x00'
# header += struct.pack(">II", len(soundData), 22050)
# header += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x73\x73\x69\x73\x74\x61\x6E\x74\x2D\x76\x69\x6C\x6C\x61\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
#VAGp header data length and sample rate are packed in bytes 11-15 and 16-20 respectively # with open(f'./OUT/VAGp/{count}.VAGp','wb') as out:
header = b'\x56\x41\x47\x70\x00\x00\x00\x20\x00\x00\x00\x00' # out.write(header)
header += struct.pack(">II", len(soundData), 22050) # out.write(soundData)
header += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x73\x73\x69\x73\x74\x61\x6E\x74\x2D\x76\x69\x6C\x6C\x61\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # out.close()
# count += 1
with open(f'./OUT/VAGp/{count}.VAGp','wb') as out:
out.write(header)
out.write(soundData)
out.close()
count += 1