Automatically make a Decent Sampler Lib by a folder of samples

Home Forums Pianobook Automatically make a Decent Sampler Lib by a folder of samples

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #1449990
    AvatarNicola Landro
    Participant

    I think that Decent Sampler is very good sampler, that work also for Linux, so I made this script that can help to have a base plugin by a folder of samples. In this way it is easy to port our libraries of sound also for this sampler and it is also a good starting point for who want to create a new one. More info about the project [there](https://gitlab.com/nicolalandro/samples_to_decent_sampler_lib/-/tree/main).

    requirements: python and librosa (installed by pip)

    
    import os
    import numpy as np
    import librosa
    import scipy
    import math
    
    SAMPLES_FOLDER = "Samples"
    OUTPUT_FILE = "preset.dspreset"
    BASE_SCRIPT_START = """
    <?xml version="1.0" encoding="UTF-8" ?>
    <DecentSampler>
        <ui bgImage="background.png" width="812" height="375">
            <tab name="main">            
                <label x="365" y="0" width="100" height="50" text="Reverb" textColor="FFFFFFFF"/>
                <control x="360" y="30" parameterName="Reverb" type="float" minValue="0" maxValue="1" textColor="FF000000" value="0.5">
                    <binding type="effect" level="instrument" position="0" parameter="FX_REVERB_WET_LEVEL"/>
                </control>
            </tab>
        </ui>
        <groups>
            <group>
    
    """
    BASE_SCRIPT_END = """
            </group>
        </groups>
        <effects>
            <effect type="reverb" wetLevel="0.5" />
        </effects>
    </DecentSampler>
    """
    
    def create_sample_line(note_number, file_path):
        return f'            <sample rootNote="{note_number}" path="{file_path}" />'
    
    def main():
        audio_samples_names = os.listdir(SAMPLES_FOLDER)
        
        samples_lines = ""
        max_iteration = len(audio_samples_names)
        for i, sample_name in enumerate(audio_samples_names):
            print(f'{i+1}/{max_iteration}')
            path = os.path.join(SAMPLES_FOLDER, sample_name)
            
            midi_number = audio_to_note(path)
            
            sample_line = create_sample_line(midi_number, path)
            samples_lines += sample_line + '\n'
                    
        lib_text = BASE_SCRIPT_START + samples_lines + BASE_SCRIPT_END
        with open(OUTPUT_FILE, 'w') as f:
            f.writelines(lib_text)
     
    def audio_to_note(path):
        print('\t', path)
        
        audio, sample_rate = librosa.load(path) # default semple rate 22500 that reduce original but it is more efficient for computation
        fundamental_frequencies, _, _ = librosa.pyin(audio, fmin=librosa.note_to_hz('C2'), fmax=librosa.note_to_hz('C7'))
        
        filtered_fundamental_frequencies = list(filter(lambda x: not np.isnan(x), fundamental_frequencies))
        frequency_mode = scipy.stats.mode(filtered_fundamental_frequencies).mode[0]
        frequency_median = np.median(filtered_fundamental_frequencies)
        frequency_mean = np.mean(filtered_fundamental_frequencies)
        print("\t\tmode:", frequency_mode, "median:", frequency_median, "mean:", frequency_mean)
        
        predicted_frequency = np.mean([frequency_mode, frequency_median])
        raw_midi_number = librosa.hz_to_midi(predicted_frequency)
        note_name = librosa.midi_to_note(raw_midi_number)
        midi_number = int(math.ceil(librosa.hz_to_midi(librosa.note_to_hz(note_name))))
        print('\t\tfrequency:', predicted_frequency, 
              'midi number:', f'{midi_number}({raw_midi_number})', 
              'note:', note_name)
        return midi_number
    
    if __name__ == "__main__":
        main()
    
    

    Usage:
    1. create a folder
    2. put background.png file (width: 812, height: 375)
    3. create a folder Samples with inside all the .wav recorded
    4. copy generate_decentsampler.py inside the folder
    5. run python3 generate_decentsampler.py
    6. it create the ‘preset.dspreset’ file that is the file to load into your decentsampler
    7. you can zip the folder and share on pianobook!

    That script is not perfect, but is a good starting point and maybe with the help of the community can become better and better.

    • This topic was modified 2 weeks, 4 days ago by AvatarNicola Landro. Reason: Add gitlab link of the code
    #1450014
    AvatarJorge Serrano
    Participant

    Thank you for sharing Nicola!

    I will take a look to you script.
    I think that could be useful not only for Linux users, but also for MacOS or Windows users too.

    Kind regards,

    Jorge

Viewing 2 posts - 1 through 2 (of 2 total)
  • You must be logged in to reply to this topic.

Follow Pianobook