surikov / webaudiofont

Use full GM set of musical instruments to play MIDI and single sounds or effects. Support for reverberation and equaliser. No plugins, no Flash. Pure HTML5 implementation compatible with desktop and mobile browser. See live examples.
https://surikov.github.io/webaudiofont/
GNU General Public License v3.0
888 stars 92 forks source link

Problem loading instruments while running #45

Closed RaulMelinte closed 5 years ago

RaulMelinte commented 5 years ago

Hi,

I'm just starting with web applications development and i can't find a way to figure out this.

I have 3 instruments at the same time, and I want to choose between all you have available. The way I do this is:

3 input select

    document.querySelector("#instrumento-melody").addEventListener("input", function(){
        melodyInstrument = InstrumentChange(this.value)
    }, false);

    document.querySelector("#instrumentoPrincipal").addEventListener("input", function(){
        mainMetronomInstrument = InstrumentChange(this.value)
    }, false);
    document.querySelector("#instrumentoSecundario").addEventListener("input", function(){
        secundaryMetronomInstrument = InstrumentChange(this.value)
    }, false);

I load all the instruments:

    let instrumento = [];
    let mainMetronomInstrument = null;
    let secundaryMetronomInstrument = null;
    let melodyInstrument = null;
    player.loader.startLoad(audioCtx, "https://surikov.github.io/webaudiofontdata/sound/0000_FluidR3_GM_sf2_file.js", "_tone_0000_FluidR3_GM_sf2_file");
    player.loader.waitLoad(function () {
    instrumento[0] = window["_tone_0000_FluidR3_GM_sf2_file"];
    player.loader.decodeAfterLoading(audioCtx, '_tone_0000_FluidR3_GM_sf2_file');
    mainMetronomInstrument = instrumento[0];
    secundaryMetronomInstrument = instrumento[0]
    melodyInstrument = instrumento[0];
    });

    player.loader.startLoad(audioCtx, "https://surikov.github.io/webaudiofontdata/sound/0010_FluidR3_GM_sf2_file.js", "_tone_0010_FluidR3_GM_sf2_file");
    player.loader.waitLoad(function () {
    instrumento[1] = window["_tone_0010_FluidR3_GM_sf2_file"];});

    player.loader.startLoad(audioCtx, "https://surikov.github.io/webaudiofontdata/sound/0020_FluidR3_GM_sf2_file.js", "_tone_0020_FluidR3_GM_sf2_file");
    player.loader.waitLoad(function () {
    instrumento[2] = window["_tone_0020_FluidR3_GM_sf2_file"];});

    player.loader.startLoad(audioCtx, "https://surikov.github.io/webaudiofontdata/sound/0030_FluidR3_GM_sf2_file.js", "_tone_0030_FluidR3_GM_sf2_file");
    player.loader.waitLoad(function () {
    instrumento[3] = window["_tone_0030_FluidR3_GM_sf2_file"];});
            .
            .
            .
          [...]

And a switch case:

    function InstrumentChange(instrument){
        console.log('cambiando');
        switch(instrument) {
            case "Acoustic Grand Piano":
                return instrumento[0];
            case "Bright Acoustic Piano":  
                return instrumento[1];                  
            case "Electric Grand Piano": 
                return instrumento[2];   
            case "Honky-tonk Piano": 
                return instrumento[3];
            case "Electric Piano 1":  
                return instrumento[4];                  
            case "Electric Piano 2":
      .
      .
      .
     [...]

Doing so works, the problem is that loading 100 instruments when page open is quite slow, I would like to load them only when they are required:

            case "Clarinet":        
                player.loader.startLoad(audioCtx, "https://surikov.github.io/webaudiofontdata/sound/0710_FluidR3_GM_sf2_file.js", "_tone_0710_FluidR3_GM_sf2_file");
                player.loader.waitLoad(function () {
                instrumento[15]= window["_tone_0710_FluidR3_GM_sf2_file"];});
                return instrumento[15];
                break;

This returns me random empty buffer.

            case "Flute":
                player.loader.startLoad(audioCtx, "https://surikov.github.io/webaudiofontdata/sound/0730_FluidR3_GM_sf2_file.js", "_tone_0730_FluidR3_GM_sf2_file");
                player.loader.waitLoad(function () {
                return window["_tone_0730_FluidR3_GM_sf2_file"];});
                break;

And this doesn't work.

Am I doing something wrong?

Thank you

surikov commented 5 years ago

What doesn't work exactly?

Buffers are empty till you decode audio or play it. See https://github.com/surikov/webaudiofont/wiki/4.2.-decodeAfterLoading

RaulMelinte commented 5 years ago

return window["_tone_0730_FluidR3_GM_sf2_file"];

returns undefined, a bug with return statement maybe?

surikov commented 5 years ago

Paste here link from https://jsbin.com/ that reproduces problem.

There are no bugs. Look to examples at https://github.com/surikov/webaudiofont#code-examples

RaulMelinte commented 5 years ago

https://jsbin.com/danadaluvu/edit?html,console,output

surikov commented 5 years ago

Open this link https://jsbin.com/muhayizego/edit?html,output

select Harpsichord from first list click Play

It works.

Look to debug messages. Look to the source. Your code is completely wrong. You load audiointo one variable, seek for other one, play third one.

Please look to examples at project page. It is enough to learn a way to use this library.