Esempio n. 1
0
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")
Esempio n. 4
0
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")
Esempio n. 5
0
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
Esempio n. 6
0
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)
Esempio n. 7
0
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')
Esempio n. 8
0
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)
Esempio n. 9
0
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)
Esempio n. 10
0
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")
Esempio n. 11
0
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(
Esempio n. 13
0
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")
Esempio n. 14
0
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..")
Esempio n. 15
0
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
Esempio n. 16
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]
Esempio n. 17
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) 
Esempio n. 18
0
 def __init__(self,sf2_file):
     Playback.sf2 = Sf2File(open(sf2_file, 'rb'))