async def regenerate_fsb(inputpath: Path, voicegen: Voicegen): print('reading', inputpath) build_successes_ = [] build_failures_ = [] # for file in data.buildpath.glob('*'): # if not file.is_dir() \ # and not file.name.startswith('fdp_') \ # and not file.name.endswith('fsb'): # file.unlink() with open(str(inputpath), 'rb') as f: fsb = fsb5.FSB5(f.read()) name = inputpath.name[:-10] lstpath = data.buildpath.joinpath(name + '.lst') fsbpath = data.outputpath.joinpath(name + '.fsb') samplenames = list(map(lambda sample: sample.name, fsb.samples)) with open(lstpath, 'w') as lst: for sample in samplenames: lst.write("%s\n" % sample) # extract existing audio print('extracting samples from', name) subprocess.check_call([ str(data.basepath.joinpath('tools/fmodextr/fmod_extr.exe').resolve()), str(inputpath.resolve()) ], cwd=str(data.buildpath.resolve()), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) print('generating', len(samplenames), 'voicelines for', name) await voicegen.genallvoicelines(samplenames, name) print('generating', fsbpath.relative_to(data.outputpath).name) result = subprocess.call([ str(data.basepath.joinpath('tools/fmod/fsbankcl.exe').resolve()), '-o', str(fsbpath), '-quality', '98', '-encryption_key', 'FDPrVuT4fAFvdHJYAgyMzRF4EcBAnKg', '-format', 'vorbis', '-thread_count', '8', '-rebuild', '-verbosity', '0', str(lstpath) ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) if result != 0: print('failed building soundbank:', fsbpath) build_failures_ += [fsbpath] else: print('sucessfully built soundbank:', fsbpath) build_successes_ += [fsbpath] # shutil.rmtree(data.buildpath, ignore_errors=True) print() return build_failures_, build_successes_
def extract_soundbank(soundbank_path: Path, dest_path: Path, extract_extensions: Extension = None): if extract_extensions: extract_extensions = set(ext.value for ext in extract_extensions) for ext in Extension: if extract_extensions and ext.value not in extract_extensions: continue ext_dest_path = dest_path / ext.value if not ext_dest_path.exists(): ext_dest_path.mkdir(parents=True, exist_ok=True) with soundbank_path.open("rb") as soundbank_file: riff = RIFF(soundbank_file) for i in range(len(riff.children) - 2): chunk = riff.children[i + 2] # read the file into a FSB5 object chunk.seek(0) chunk.seek(0x20 - chunk.offset % 0x20) fsb = fsb5.FSB5(chunk.read()) # from python-fsb5 repo == # get the extension of samples based off the sound format specified in the header ext = fsb.get_sample_extension() if extract_extensions and ext not in extract_extensions: continue for sample in fsb.samples: logger.info( "Extracting %s.%s (%sHz, %s channels, %s samples)", sample.name, ext, sample.frequency, sample.channels, sample.samples, ) try: with (dest_path / ext / f"{sample.name}.{ext}").open("wb") as out_file: out_file.write(fsb.rebuild_sample(sample)) except LibraryNotFoundException as err: logger.error( "Failed to extract files for extension %s: %s", ext, err) return logger.info("Extracted %s %s files from bank %s", len(fsb.samples), ext, i)
def __init__(self, path: str): if path.endswith('.ogg'): data, self.samplerate = sf.read(path) data *= 32767 / max(abs(data)) self.data = data.astype(numpy.int16) elif path.endswith('.fsb'): with open(path, "rb") as f: data = fsb5.FSB5(f.read()) print(data.get_sample_extension()) for sample in data.samples: print(f'frq: {sample.frequency}') print(f'ch: {sample.channels}') print(f'sa: {sample.samples}') rebuilt = data.rebuild_sample(data.samples[0]) print(rebuilt) else: raise Exception(f"Unsupported file type {path}")
if len(sys.argv) < 2: print("ERROR: file argument missing") sys.exit(1) args = sys.argv[1:] print("MAIN") for x in args: if os.path.isfile(x): print(x) else: print("ERROR: note a file - ", x) with open(x, 'rb') as f: fsb = fsb5.FSB5(f.read()) print(fsb.header) ext = fsb.get_sample_extension() # iterate over samples for sample in fsb.samples: # print sample properties print('''\t{sample.name}.{extension}: Frequency: {sample.frequency} Channels: {sample.channels} Samples: {sample.samples}'''.format(sample=sample, extension=ext)) # rebuild the sample and save with open('{0}.{1}'.format(sample.name, ext), 'wb') as f: rebuilt_sample = fsb.rebuild_sample(sample)
#Songs are compressed into FSB5 files and named some_string.resource #Song name is in file with the same as the file above, but without .resource res_file_list = glob.glob(os.path.join(source_dir, "*.resource")) for res_file in res_file_list: if ("sharedasset" in res_file): continue #Get real name name_file = res_file.split(".")[0] real_name = get_real_name(name_file) if (real_name is None): continue #Extract FSB5 with open(res_file, 'rb') as fp: fsb = fsb5.FSB5(fp.read()) audio_data = fsb.samples[0] #Check extension ext = fsb.get_sample_extension() if (ext is not "mp3"): continue #Build audio save path audio_path = os.path.join(destination_dir, real_name.decode("ascii").strip()) while (os.path.isfile(audio_path)): audio_path += "d" audio_path = audio_path + "." + ext
def open_soundbank(pak: LPakArchive, fname: str, prefix: str = '') -> Iterator[fsb5.FSB5]: with pak.open(fname, 'rb') as sb: yield fsb5.FSB5(sb, prefix=prefix)