jet2jet / js-synthesizer

Synthesizer library for web-based JS program, using with Web Audio or etc.
BSD 3-Clause "New" or "Revised" License
58 stars 8 forks source link

Reverb settings in SynthesizerSettings do not create reverb #22

Closed Thysbelon closed 1 year ago

Thysbelon commented 1 year ago

Hello. I am trying to add a large amount of reverb to the playback of a midi, but none of the settings in SynthesizerSettings create reverb that I can hear. I am using an AudioWorklet. here is my code:

var sfontBuffer;
var smfBuffer;
var context;
var synth;

function StartJams(){
console.log('startjams');

(async function(){
    let response = await fetch('ExtractedSoundbank.sf3')
    sfontBuffer = await response.arrayBuffer()
    response = await fetch('Super Smash Bros. (U) 0000000A 00B379FC cut.mid')
    smfBuffer = await response.arrayBuffer()
})();

JSSynth.waitForReady().then(loadSynthesizer);

async function loadSynthesizer() {
    context = new AudioContext();
    await context.audioWorklet.addModule('https://cdn.jsdelivr.net/npm/js-synthesizer@1.8.5/externals/libfluidsynth-2.3.0-with-libsndfile.js')
    await context.audioWorklet.addModule('https://cdn.jsdelivr.net/npm/js-synthesizer@1.8.5/dist/js-synthesizer.worklet.min.js');
    synth = new JSSynth.AudioWorkletNodeSynthesizer();
    synth.init(context.sampleRate); //adding settings here has no effect
    var audioNode = synth.createAudioNode(context, {reverbActive:true, reverbLevel:1, reverbRoomSize:0.83, reverbWidth:1});
    audioNode.connect(context.destination);
    await synth.loadSFont(sfontBuffer)
    await synth.addSMFDataToPlayer(smfBuffer);
    await synth.playPlayer();
    while (true) {
        console.log("loop")
        await synth.waitForPlayerStopped()
        await synth.seekPlayer(1440)
        await synth.playPlayer();
    }
}

}

The only setting that has any effect at all is reverbWidth; if I set it to 100, it creates white noise, but it does not create reverb.

Also, I tried to change my code to not use AudioWorklets to see if that would get reverb to work, but I got "fluidsynth: error: EOF while attempting to read 8 bytes":

var sfontBuffer;
var smfBuffer;
var context;
var synth;

function StartJams(){
console.log('startjams');

(async function(){
    let response = await fetch('ExtractedSoundbank.sf3');
    sfontBuffer = await response.arrayBuffer();
    response = await fetch('Super Smash Bros. (U) 0000000A 00B379FC cut.mid');
    smfBuffer = await response.arrayBuffer();
})();

JSSynth.waitForReady().then(loadSynthesizer);

async function loadSynthesizer() {
    context = new AudioContext();
    synth = new JSSynth.Synthesizer();
    synth.init(context.sampleRate);
    var node = synth.createAudioNode(context, 8192);
    node.connect(context.destination);
    await synth.loadSFont(sfontBuffer);
    await synth.addSMFDataToPlayer(smfBuffer);
    await synth.playPlayer();
    while (true) {
        console.log("loop")
        await synth.waitForPlayerStopped()
        await synth.seekPlayer(1440)
        await synth.playPlayer();
    }

}

}

Here is a link to the sf3 and midi I was using.

jet2jet commented 1 year ago

I tried with native FluidSynth 2.3.0 (Windows x64 version), but it seems that the result is same for js-synthesizer.
I don't know the details, but I think something may be wrong in the soundfont. (If the soundfont is OK, then FluidSynth has some bugs for reverb.)

Please confirm whether the reverb settings in FluidSynth affects the sound, and report to the FluidSynth project if the problem still occurs.

Also, I tried to change my code to not use AudioWorklets to see if that would get reverb to work, but I got "fluidsynth: error: EOF while attempting to read 8 bytes":

The cause of this problem is that sfontBuffer is not initialized when calling synth.loadSFont(sfontBuffer);. The following code works:

var sfontBuffer;
var smfBuffer;
var context;
var synth;

async function StartJams(){
console.log('startjams');

// Waiting for loading data
await (async function(){
    let response = await fetch('ExtractedSoundbank.sf3');
    sfontBuffer = await response.arrayBuffer();
    response = await fetch('Super Smash Bros. (U) 0000000A 00B379FC cut.mid');
    smfBuffer = await response.arrayBuffer();
})();

JSSynth.waitForReady().then(loadSynthesizer);

async function loadSynthesizer() {
    context = new AudioContext();
    synth = new JSSynth.Synthesizer();
    synth.init(context.sampleRate);
    var node = synth.createAudioNode(context, 8192);
    node.connect(context.destination);
    await synth.loadSFont(sfontBuffer);
    await synth.addSMFDataToPlayer(smfBuffer);
    await synth.playPlayer();
    while (true) {
        console.log("loop")
        await synth.waitForPlayerStopped()
        await synth.seekPlayer(1440)
        await synth.playPlayer();
    }

}

}
Thysbelon commented 1 year ago

Thank you.