def decode_selected(path, inst_index, selected_bags, global_bag_index, user_title=None, user_dir=None): with open(path, 'rb') as file: sf2 = Sf2File(file) bags_to_decode = \ [sf2.instruments[inst_index].bags[n] for n in selected_bags] if selected_bags \ else sf2.instruments[inst_index].bags[1:] if global_bag_index != None \ else sf2.instruments[inst_index].bags for bag in bags_to_decode: bag.sample.sm24_offset = None is_valid, error_msg = check_is_valid_sample(bag.sample) if not is_valid: error(error_msg) return False if selected_bags: print_debug(DEBUG_FLAG, 'Selected Sample is {}'.format(bag.sample.name)) global_bag = sf2.instruments[inst_index].bags[global_bag_index] if global_bag_index != None else None file_title = user_title if user_title else sf2.instruments[inst_index].name file_title = re.sub(r'[\W]+', '', file_title) if user_dir is not None: export_samples(bags_to_decode, global_bag, len(bags_to_decode), file_title=file_title, file_dir=user_dir) else: export_samples(bags_to_decode, global_bag, len(bags_to_decode), file_title=file_title) return True
def loadSoundfont(self): """ This function is constrained by the size of main memory. It will instantiate an object for each instrument which will contain a list of all the layers/bags that make up said instrument. The data used us no-where near the entirety of the Soundfont/SF2 so available main memory does not need to be greater than the size of the SF2. I don't see this as a serious concern but felt it should be noted. """ with open(self.inFile, 'rb') as sf2_file: sf2 = Sf2File(sf2_file) sf2Instruments = list() inst_index = 0 for inst in sf2.instruments: if inst.name == 'EOI': break sf2Instruments.append(sf2elements.Instrument( inst.name, inst_index)) inst_index += 1 bag_index = 0 for bag in inst.bags: if bag.sample is None: sf2Instruments[-1].setGlobalBag(bag_index) elif bag.sample is not None and bag.sample not in sf2Instruments[ -1].Samples: sf2Instruments[-1].Samples.append( sf2elements.Sample(bag.sample.name, bag_index, bag.key_range, bag.sample.duration)) bag_index += 1 # sorted ascending by ascii value of instrument names # preserves case but sorts indifferent to it # the result is upper and lower case being intermingled sf2Instruments.sort(key=lambda x: str.lower(x.i_name)) self.setInstrumentList(sf2Instruments)
def findGMInstrument(name, look_in_soundfont=None, bank=None): # Allow manually selected instruments try: return (bank, int(name)) except: pass name = name.replace("(", '').replace(')', '') # Try to find a matching patch name in the soundfont if look_in_soundfont: try: from sf2utils.sf2parse import Sf2File with open(look_in_soundfont, 'rb') as sf2_file: sf2 = Sf2File(sf2_file) # Names x = [ i[0].split(b"\0")[0].decode("utf8") for i in sf2.raw.pdta['Phdr'] ] except Exception as e: logging.exception("Can't get metadata from this soundfont") print("Error looking through soundfont data", e) x = [] # Indexes for i in range(len(x)): n = x[i].lower() n = n.replace("(", '').replace(')', '') n = n.split(" ") match = True for j in name.lower().split(" "): if not j in n: # Bank 128 is reserved for drums so it can substitute for drum related words, # It's still a match if not (j in ('kit', 'drums', 'drum') and sf2.raw.pdta['Phdr'][i][2] == 128): match = False if match: if bank == None: return (sf2.raw.pdta['Phdr'][i][2], sf2.raw.pdta['Phdr'][i][1]) return (bank, sf2.raw.pdta['Phdr'][i][1]) x = getGMInstruments() for i in x: n = x[i].lower() n = n.replace("(", '').replace(')', '') n = n.split(" ") match = True for j in name.lower().split(" "): if not j in n: match = False if match: return (bank or 0, i) raise ValueError("No matching instrument")
def generate_pcm_header(sf2_filename, pcm_sample_rate=22050): # Given an sf2 file, extract some pcm and write pcm.h from sf2utils.sf2parse import Sf2File import resampy import numpy as np p = open("main/pcm.h", "w") p.write("// Automatically generated by alles.generate_pcm_header()\n") p.write("#ifndef __PCM_H\n#define __PCM_H\n") offsets = [] offset = 0 int16s = [] sf2 = Sf2File(open(sf2_filename, 'rb')) for sample in sf2.samples: try: if (sample.is_mono): s = {} s["name"] = sample.name floaty = (np.frombuffer(bytes(sample.raw_sample_data), dtype='int16')) / 32768.0 resampled = resampy.resample(floaty, sample.sample_rate, pcm_sample_rate) samples = np.int16(resampled * 32768) int16s.append(samples) s["offset"] = offset s["length"] = samples.shape[0] offset = offset + samples.shape[0] offsets.append(s) except AttributeError: pass all_samples = np.hstack(int16s) p.write( "#define PCM_SAMPLES %d\n#define PCM_LENGTH %d\n#define PCM_SAMPLE_RATE %d\n" % (len(offsets), all_samples.shape[0]), pcm_sample_rate) p.write("const uint32_t offset_map[%d] = {\n" % (len(offsets) * 2)) for o in offsets: p.write(" %d, %d, /* %s */\n" % (o["offset"], o["length"], o["name"])) p.write("};\n") p.write("const int16_t pcm[%d] = {\n" % (all_samples.shape[0])) column = 15 count = 0 for i in range(int(all_samples.shape[0] / column)): p.write(" %s,\n" % (",".join([ str(d).ljust(6) for d in all_samples[i * column:(i + 1) * column] ]))) count = count + column print("count %d all_samples.shape %d" % (count, all_samples.shape[0])) if (count != all_samples.shape[0]): p.write(" %s\n" % (",".join([str(d).ljust(6) for d in all_samples[count:]]))) p.write("};\n\n#endif // __PCM_H\n")
def test_basic_parse(): """make sure that parsing a simple file loads the right amount of instruments, samples and presets""" with open_file('sf2utils_test.sf2') as file: sf2_file = Sf2File(file) assert len(sf2_file.instruments) == 3 assert len(sf2_file.samples) == 3 assert len(sf2_file.presets) == 2 assert sf2_file.instruments[0].name == 'inst1' assert sf2_file.instruments[1].name == 'inst2' assert sf2_file.presets[0].bank == 13 assert sf2_file.presets[0].preset == 37
def listSf2Info(sf2FilePath): with open(sf2FilePath, 'rb') as sf2_file: sf2 = Sf2File(sf2_file) # We do not care instrument by now. # for instrument in sf2.instruments: # if instrument.name != 'EOI': # pprint.pprint(vars(instrument)) # for bag in instrument.bags: # pprint.pprint(bag.__dir__()) for sample in sf2.samples: pprint.pprint(sample)
def main(name='SSEQ_0041.sf2'): sf2_file = open(name, 'rb') sf2 = Sf2File(sf2_file) samples = sorted(sf2.samples[:-1], key=lambda s: s.name) # type: List[Sample] name2sample = {sample.name : sample for sample in samples} # type: Dict[str, Sample] with pushd(WAV+WAV2AMK+'samples/'+PROJECT): for wat in glob.glob('*'): os.remove(wat) with pushd('wav'): folders = [f[:-1] for f in glob.glob('*/') if '~' not in f] configs = [f[:f.find('\\')] for f in glob.glob('*/*.cfg*') if '~' not in f] if len(folders) != len(configs): raise Exception(set(folders) - set(configs)) for cfgname in sorted(glob.glob(r'*/*.cfg')): # type: str cfgname = cfgname.replace('\\', '/') convertCfg(cfgname, name2sample) os.system('build.cmd')
def getFromSf2(sf2FilePath, sampleName): with open(sf2FilePath, 'rb') as sf2_file: sf2 = Sf2File(sf2_file) for sample in sf2.samples: if sample.name == sampleName: if sample.sample_width == 1: upackStr = '<b' elif sample.sample_width == 2: upackStr = '<h' else: raise RuntimeError('Unsupported sample width') samples = [ sampleValue[0] for sampleValue in struct.iter_unpack( upackStr, sample.raw_sample_data) ] attackSamples = samples[0:sample.start_loop] loopSamples = samples[sample.start_loop:sample.end_loop] sampleMidiNote = sample.original_pitch return (sampleName, sampleMidiNote, np.array(attackSamples), np.array(loopSamples), sample.sample_width, sample.sample_rate, 1)
def main( wav_in: Path, cfg_in: IO[str], brr_out: Path, sf2_in: Optional[IO[bytes]], # yaml_out: Optional[Path], decode_loops: Optional[int], verbose: int, ): # Begin wav2brr setup decode_loops = coalesce(decode_loops, 1) opt = CliOptions(verbose=verbose, decode_loops=decode_loops) if sf2_in is not None: sf2 = Sf2File(sf2_in) samples = sorted(sf2.samples[:-1], key=lambda s: s.name) # type: List[Sf2Sample] name_to_sample = {sample.name: sample for sample in samples} # type: Dict[str, Sf2Sample] else: name_to_sample = {} # Create .brr, decode to .wav result = convert_cfg(opt, wav_in, brr_out, cfg_in, name_to_sample)
def generate_alles_pcm_header(pcm_sample_rate=22050): from sf2utils.sf2parse import Sf2File import resampy import numpy as np import struct # These are the indexes that we liked and fit into the flash on Alles ESP32. You can download the sf2 files here: # https://github.com/vigliensoni/soundfonts/blob/master/hs_tr808/HS-TR-808-Drums.sf2 # https://ftp.osuosl.org/pub/musescore/soundfont/MuseScore_General/MuseScore_General.sf2 # Put them in the sounds/ folder. fns = (("sounds/HS-TR-808-Drums.sf2", False), ('sounds/MuseScore_General.sf2', True)) good = [0, 3, 8, 11, 14, 16, 17, 18, 20, 23, 25, 26, 29, 30, 31, 32, 37, 39, 40, 42, 47, 49, 50, 52, 58, 63, 69, 74, 76, 80, 83, 85, 86, 95, 96, 99, 100, 101, 107, 108, 109, 112, 116, 117, 118, 120, 127, \ 130, 134, 136, 145, 149, 155, 161, 165, 166, 170, 171, 175, 177, 178, 183, 192, 197, 198, 200, 204] offsets = [] offset = 0 int16s = [] samples = [] sample_counter = 0 my_sample_counter = 0 orig_map = {} for (fn, is_inst) in fns: sf2 = Sf2File(open(fn, 'rb')) if is_inst: for i, inst in enumerate(sf2.instruments[:-1]): b = inst.bags[int(len(inst.bags) / 2)] if (sample_counter in good): samples.append(b.sample) orig_map[my_sample_counter] = sample_counter my_sample_counter += 1 sample_counter += 1 else: for sample in sf2.samples[:-1]: if (sample_counter in good): samples.append(sample) orig_map[my_sample_counter] = sample_counter my_sample_counter += 1 sample_counter += 1 for sample in samples: try: s = {} s["name"] = sample.name floaty = (np.frombuffer(bytes(sample.raw_sample_data), dtype='int16')) / 32768.0 resampled = resampy.resample(floaty, sample.sample_rate, pcm_sample_rate) samples_int16 = np.int16(resampled * 32768) #floats.append(resampled) int16s.append(samples_int16) s["offset"] = offset s["length"] = resampled.shape[0] s["loopstart"] = int( float(sample.start_loop) / float(sample.sample_rate / pcm_sample_rate)) s["loopend"] = int( float(sample.end_loop) / float(sample.sample_rate / pcm_sample_rate)) s["midinote"] = sample.original_pitch offset = offset + resampled.shape[0] offsets.append(s) except AttributeError: print("skipping %s" % (sample.name)) all_samples = np.hstack(int16s) # Write packed .bin file of pcm[] as well as .h file to write as an ESP32 binary partition b = open("main/amy/pcm.bin", "wb") for i in range(all_samples.shape[0]): b.write(struct.pack('<h', all_samples[i])) b.close() p = open("main/amy/pcm.h", "w") p.write( "// Automatically generated by amy_headers.generate_pcm_header()\n") p.write("#ifndef __PCM_H\n#define __PCM_H\n") p.write( "#define PCM_SAMPLES %d\n#define PCM_LENGTH %d\n#define PCM_SAMPLE_RATE %d\n" % (len(offsets), all_samples.shape[0], pcm_sample_rate)) p.write("const pcm_map_t pcm_map[%d] = {\n" % (len(offsets))) for i, o in enumerate(offsets): p.write(" /* [%d] %d */ {%d, %d, %d, %d, %d}, /* %s */\n" % (i, orig_map[i], o["offset"], o["length"], o["loopstart"], o["loopend"], o["midinote"], o["name"])) p.write("};\n") p.write("\n#endif // __PCM_H\n") p.close() p = open("main/amy/pcm_samples.h", 'w') p.write( "// Automatically generated by amy_headers.generate_pcm_header()\n") p.write("#ifndef __PCM_SAMPLES_H\n#define __PCM_SAMPLES_H\n") p.write("const int16_t pcm[%d] = {\n" % (all_samples.shape[0])) column = 15 count = 0 for i in range(int(all_samples.shape[0] / column)): p.write( " %s,\n" % (",".join([("%d" % (d)).ljust(8) for d in all_samples[i * column:(i + 1) * column]]))) count = count + column print("count %d all_samples.shape %d" % (count, all_samples.shape[0])) if (count != all_samples.shape[0]): p.write(" %s\n" % (",".join([("%d" % (d)).ljust(8) for d in all_samples[count:]]))) p.write("};\n") p.write("\n#endif // __PCM_SAMPLES_H\n")
def main(argv): global DEBUG_FLAG # Disable warning logging to prevent sf2utils from logging any un-needed messages logging.disable(logging.WARNING) # Read args from the command line and open file try: path, outFile = read_args(argv) with open(path, 'rb') as sf2_file: sf2 = Sf2File(sf2_file) except FileNotFoundError as err: print("ERROR: " + str(err.args[1]) + ": " + path) print_usage() sys.exit(2) except: print("ERROR: An unexpected error occured while opening the file") sys.exit(2) clear_screen() print(' WELCOME ') # print out some info: # version, date, etc... options = ('Select by Instrument', 'Quit') options2 = ('Select Again', 'Save and Quit') while True: choice = menu(options) if choice == 1: # select instrument clear_screen() # Returns a List of sf2Instrument.name instruments = [x.name for x in sf2.instruments] print('') instruments.remove('EOI') print_menu(instruments) instrument = safe_input( 'Select Instrument [1-{}]: '.format(len(instruments)), int, 1, len(instruments)) print('') # for the selected instrument, go through all bags and # retrieve sample(s) instrument -= 1 bag_to_sample = [] # lists (bag index, sample) tuples bag_index = 0 global_bag_index = None # Create a list of tuples that hold bag_index to sample pairs for bag in sf2.instruments[instrument].bags: if bag.sample is None: global_bag_index = bag_index elif bag.sample is not None and bag.sample not in bag_to_sample: bag_to_sample.append((bag_index, bag.sample)) bag_index += 1 samples = [x[1] for x in bag_to_sample] sample_names = [x.name for x in samples] print('{} contains {} samples.'.format( sf2.instruments[instrument].name, len(sample_names))) method = menu(('Export All Samples', 'Select Samples to Export')) if method == 1: # decode all samples for instrument decode_all(path, instrument, global_bag_index) print( 'All samples for instrument decoded successfully. Exiting Program.' ) return else: # decode selected samples for instrument selected_bags = [] while True: # select which samples to decode clear_screen() print('Select Samples to Export\n') print_menu(sample_names) sample = safe_input( 'Select Sample [1-{}]: '.format(len(sample_names)), int, 1, len(sample_names)) print_debug( DEBUG_FLAG, 'Selected Sample is {}'.format( samples[sample - 1].name)) if (bag_to_sample[sample - 1][0] not in selected_bags): selected_bags.append(bag_to_sample[sample - 1][0]) i_result = menu(options2) if i_result == 1: # select another sample continue elif i_result == 2: # decode list of selected samples decode_selected(path, instrument, selected_bags, global_bag_index) print( 'Selected samples for instrument decoded successfully. Exiting Program.' ) return elif choice == 2: # exit print('Program Terminated by User') return else: # shouldn't be reached input("Wrong option selection. Enter any key to try again..")
SF2DIR = '/sf2/' for file in os.listdir(os.getcwd() + SF2DIR): if os.path.splitext(file)[-1].lower() == ".txt": os.remove(os.getcwd() + SF2DIR + file) listFile = [] for file in sorted(os.listdir(os.getcwd() + SF2DIR)): if file.endswith('.txt'): continue print(file) with open(os.getcwd() + SF2DIR + str(file), 'rb') as sf2_file: sf2 = Sf2File(sf2_file) sf2Name = str(os.path.splitext(file)[0]) if len(sf2Name) > 20: sf2Name = sf2Name[0:20] sf2Name = sf2Name.rstrip().replace(' ', '_') presetsList = [] presets = sf2.raw.pdta["Phdr"] for preset in presets: instName = preset.name.rstrip('\x00').replace(' ', '_').rstrip() if instName[0:3] != "EOP": # End of presets tags presetsList.append([preset.bank, preset.preset, instName]) print(
def run(filePaths): ''' Generate *.swift files for each SoundFont (sf2) file in the current directory. The Swift files will contain a custom SoundFont definition that lists all of the patches found in the SF2 file. ''' registrations = '' for filePath in filePaths: print "...processing", filePath # Load the SF2 file and get the patches / presets in it with open(filePath, 'rb') as sf2File: sf2 = Sf2File(sf2File) presets = [(getattr(z, 'bank', None), getattr(z, 'preset', None), getattr(z, 'name', None)) for z in sf2.presets] if presets[-1][0] == None: del presets[-1] presets.sort() print "...found", len(presets), "presets in file" # Generate the Swift file with the SoundFont definition for the SF2 file filePath = os.path.basename(os.path.splitext(filePath)[0]) valid = string.letters + string.digits + '_' name = filter(lambda a: a in valid, sf2.info.bank_name) registrations += '{}SoundFont.name: {}SoundFont,\n'.format( name, name) # Generate a header for the file and then write out all of the preset names year = date.today().year with open('./' + filePath + '.swift', 'w') as swiftFile: swiftFile.write('''// // SoundFont // // Created by Brad Howes // Copyright (c) {} Brad Howes. All rights reserved. // // NOTE: this file was autogenerated by the `catalog.py` script. let {}SoundFont = SoundFont("{}", fileName: "{}", [ '''.format(year, name, sf2.info.bank_name, filePath)) for index, each in enumerate(presets): swiftFile.write( ' Patch({:30} {:3d}, {:3d}, {:3d}),\n'.format( '"' + each[2] + '",', each[0], each[1], index)) swiftFile.write('])\n') # Now that we have processed all of the SF2 files, update the ../SoundFont.swift file so that it # knows about all of the SF2 patches. Read in the current file. print "...updating ../SoundFont.swift file" with open('../SoundFont.swift', 'r') as sf: contents = sf.read() # Replace all of the current lines between BEGIN and END comments with the contents # of `registrations` that was generated above begin = contents.find('// -BEGIN-') if begin == -1: raise "*** missing '// -BEGIN-' token in SoundFont.swift file" end = contents.find('// -END-') if end == -1: raise "*** missing '// -END-' token in SoundFont.swift file" contents = contents[:begin] + '// -BEGIN-\n' + registrations + contents[ end:] with open('../SoundFont.swift', 'w') as sf: sf.write(contents) print("...done")
def main(argv): global DEBUG_FLAG # Disable warning logging to prevent sf2utils from logging any un-needed messages logging.disable(logging.WARNING) path = None try: opts, args = getopt.getopt(argv, 'di:o:', ['ifile=', 'ofile=']) except getopt.GetoptError: print('INVALID ARGUMENTS') sys.exit(2) for opt, arg in opts: if opt == '-d': DEBUG_FLAG = True elif opt in ('-i', '--ifile'): path = arg elif opt in ('-o', '--ofile'): outFile = arg print(150*'\n') print(' WELCOME ') # print out some info: # version, date, etc... with open(path, 'rb') as sf2_file: sf2 = Sf2File(sf2_file) options = ('Select by Instrument', 'Quit') options2 = ('Select Again', 'Save and Quit') while True: choice = menu(options) if choice == 1: # Returns a List of sf2Instrument.name instruments = [x.name for x in sf2.instruments] print('') instruments.remove('EOI') print_menu(instruments) instrument = safe_input('Select Instrument [1-{}]: '.format(len(instruments)), int, 1, len(instruments)) print('') # for the selected instrument, go through all bags and # retrieve sample(s) instrument -= 1 bag_to_sample = [] # lists (bag index, sample) tuples bag_index = 0 global_bag_index = None # Create a list of tuples that hold bag_index to sample pairs for bag in sf2.instruments[instrument].bags: if bag.sample is None: global_bag_index = bag_index elif bag.sample is not None and bag.sample not in bag_to_sample: bag_to_sample.append((bag_index, bag.sample)) bag_index += 1 samples = [x[1] for x in bag_to_sample] sample_names = [x.name for x in samples] print('{} contains {} samples.'.format(sf2.instruments[instrument].name, len(sample_names))) method = menu(('Export All Samples', 'Select Samples to Export')) if method == 1: decode_all(path, instrument, global_bag_index) sys.exit('All samples for instrument decoded successfully. Exiting Program.') else: selected_bags = [] while True: print_menu(sample_names) sample = safe_input('Select Sample [1-{}]: '.format(len(sample_names)), int, 1, len(sample_names)) print_debug(DEBUG_FLAG, 'Selected Sample is {}'.format(samples[sample-1].name)) if(bag_to_sample[sample-1][0] not in selected_bags): selected_bags.append(bag_to_sample[sample-1][0]) i_result = menu(options2) if i_result == 1: continue elif i_result == 2: decode_selected(path, instrument, selected_bags, global_bag_index) sys.exit('Selected samples for instrument decoded successfully. Exiting Program.') elif choice == 2: sys.exit('Program Terminated by User') else: # shouldn't be reached input("Wrong option selection. Enter any key to try again..")
def main(argv=None): program_name = os.path.basename(sys.argv[0]) program_version = "v0.9" program_build_date = "%s" % __updated__ program_version_string = 'sf2toxrni %s (%s)' % (program_version, program_build_date) program_longdesc = '''Convert sf2 file into renoise instrument''' program_license = "GPL v3+ 2016-2017 Olivier Jolly" if argv is None: argv = sys.argv[1:] try: parser = argparse.ArgumentParser(epilog=program_longdesc, description=program_license) parser.add_argument( "-c", "--force-center", dest="force_center", action="store_true", default="False", help= "force panning of generated samples to center [default: %(default)s]" ) parser.add_argument("-d", "--debug", dest="debug", action="store_true", default=False, help="debug parsing [default: %(default)s]") parser.add_argument( "-e", "--encode", dest="encoding", choices=[ENCODING_NONE, ENCODING_FLAC, ENCODING_OGG], default=ENCODING_FLAC, help="encode samples into given format [default: %(default)s]") parser.add_argument( "-f", "--force", dest="force", default=False, action="store_true", help="force overwriting existing files [default: %(default)s]") parser.add_argument("-q", "--quiet", dest="quiet", action="store_true", default=False, help="quiet operation [default: %(default)s]") parser.add_argument("-i", "--instrument", dest="instruments_index", action="append", type=int, help="instrument index to extract [default: all]") parser.add_argument("--no-expand-keymap", dest="no_expand_keymap", action="store_true") parser.add_argument( "-o", "--ouput-dir", dest="output_dir", help="output directory [default: current directory]") parser.add_argument("-t", dest="template", help="template filename [default: %(default)s]", default="empty-31.xrni") parser.add_argument( "-u", "--unused", dest="show_unused", action="store_true", default=True, help="show unused generators [default: %(default)s]") parser.add_argument("--no-unused", dest="show_unused", action="store_false") parser.add_argument("-v", "--version", action="version", version=program_version_string) parser.add_argument("sf2_filename", help="input file in SoundFont2 format", nargs="+") # process options opts = parser.parse_args(argv) except Exception as e: indent = len(program_name) * " " sys.stderr.write(program_name + ": " + repr(e) + "\n") sys.stderr.write(indent + " for help use --help") return 2 if opts.debug: logging.root.setLevel(logging.DEBUG) else: logging.root.setLevel(logging.INFO) for sf2_filename in opts.sf2_filename: if not opts.quiet: print("Reading instruments from '{}'".format(sf2_filename)) with open(sf2_filename, "rb") as sf2_file: sf2 = Sf2File(sf2_file) # print(sf2.pretty_print()) sf2_to_xrni = Sf2ToXrni(**vars(opts)) for instrument_idx, sf2_instrument in enumerate(sf2.instruments): if sf2_instrument.is_sentinel(): continue if opts.instruments_index and instrument_idx not in opts.instruments_index: continue if not opts.quiet: print("Converting '{}'...".format(sf2_instrument.name), end='') # noinspection PyBroadException try: renoise_instrument = RenoiseInstrument( template_filename=opts.template) sf2_to_xrni.convert_instrument(sf2_instrument, renoise_instrument) if not opts.no_expand_keymap: expand_keymap(renoise_instrument) output_filename = os.path.join( opts.output_dir or '', '{}_{}.xrni'.format(instrument_idx, renoise_instrument.name)) # noinspection PyTypeChecker renoise_instrument.save(output_filename, overwrite=opts.force) if not opts.quiet: print(" saved {}".format(output_filename)) except Exception: if not opts.quiet: print(" FAILED") logging.exception("Failed to convert instrument") # pprint.pprint(sf2.samples) # sf2.samples[3].export('/tmp/test.wav') # pprint.pprint(sf2.presets) # pprint.pprint(sf2.instruments) # # for instrument in sf2.instruments: # print(instrument.pretty_print()) return 0
def getFontPresets(path_sfont) -> List[Tuple[int, int, str]]: with open(path_sfont, "rb") as fbuf: sf = Sf2File(fbuf) #< parse sf2 return [(p.bank, p.preset, p.name) for p in sf.build_presets() if len(p.bags) != 0]
from sf2utils.sf2parse import Sf2File from pprint import pprint from sys import argv try: file_path = argv[1] except: raise ValueError('Missing command line argument for <path-to-sf2-file>') try: with open(file_path,'rb') as f: sf2 = Sf2File(f) except: raise FileNotFoundError('Error in reading file. Make sure path is correct and is an sf2 file.') print("\n\033[1;32mInfo from file:\033[0m") pprint(sf2.info) print(f'\n\033[1;32mSample offset (bytes):\033[0m {sf2.raw.smpl_offset}') print("\n\033[1;32mPresets:\033[0m") print("\033[0;36mMore options: \033[0m\n-presets (list preset data)\n-samples (list sample data)") # pprint(sf2.presets) if '-presets' in argv: print("\n\033[1;32mPresets:\033[0m") pprint(sf2.presets) if '-samples' in argv: print("\n\033[1;32mSamples:\033[0m") pprint(sf2.samples)
def __init__(self,sf2_file): Playback.sf2 = Sf2File(open(sf2_file, 'rb'))