marchingband / wvr

Home of WVR, an open source, Arduino compatible, ESP32-based Sample Player and Audio Framework.
GNU General Public License v3.0
65 stars 9 forks source link

Support .sfz files #55

Open marchingband opened 1 year ago

marchingband commented 1 year ago

https://www.polyphone-soundfonts.com/ https://sfzformat.com/software/tools/

marchingband commented 1 year ago

attn #56 in this file: https://github.com/marchingband/wvr_ui/blob/xml/src/helpers/sfz.js I have a first try at implementing this beta binary is here: https://github.com/marchingband/wvr_binaries/blob/main/wvr_xml/wvr_xml_rc.ino.bin

it supports:

pitch_keycenter lokey hikey (these 3 work to interpolate pitches) hivel (this one sets the upper breakpoint for racks) key loop_mode (you can set 'loop_sustain' for ASR_LOOP or "one_shot" for ignore note off) volume group (this is exclusive group or mute group (0 == none)) reverb_wet disto_wet pan loop_start loop_end polyphony_stealing (this is the priority) sample

file button: you can select all the sound files and the .sfz using shift or command-click, command-A, etc from the file dialog folder button: you can select a folder with all that stuff inside, nesting directories is ok, they will all be found. There is a button at the bottom of the global menu in the WEB GUI for each way.

Gnuv commented 1 year ago

I switch to github, maybe it’s more convenient for you.

Some bugs that I found :

pitch_keycenter= lokey= hikey= and hivel= seems to work well :)

marchingband commented 1 year ago

Unfortunately these must be problems with the sfz parsing library I am using, which doesn't have a github. https://www.npmjs.com/package/sfz-parser

It's a regex parser, I hate regex, but it's MIT licensed so we can modify and republish it. I will take a look.

marchingband commented 1 year ago
function transform(sfzText) {
    sfzText = sfzText.replace(/\/\/.*$/gm, "");
    return matchAll(sfzText, /<(.*?)>\s([\s\S]*?)((?=<)|\Z)/gm).map(function (res) {
        var kvs = matchAll(res[2], /(.*?)=(.*?)($|\s(?=.*?=))/gm);
        var prop = {};
        kvs.forEach(function (kv) {
            prop[kv[1].replace(/\s/gm, "")] = /^\d*$/g.test(kv[2])
                ? Number(kv[2])
                : kv[2];
            if (/^[a-gA-G]#?\d$/.test(kv[2]))
                prop[kv[1]] = name2num(kv[2]);
        });
        if (prop.sample)
            prop.sample = prop.sample.replace(/\\/g, "/");
        return {
            type: res[1],
            property: prop,
        };
    });
}

obvious right?

Gnuv commented 1 year ago

Whaou !

For now, we can put a blank < region > at the end and use MIDI numbers instead of note names ^^

marchingband commented 1 year ago

Ok, good to know. its possible I will end up writing my own parser anyhow, because I can't find a JavaScript parser for decentSampler. They are very similar and it would only take a few minutes to adapt a parser for one to the other.