Tone.js Tone.BufferSource: buffer is either not set or not loaded

4.1k Views Asked by At

Tone.BufferSource: buffer is either not set or not loaded. This error occurs in try/catch block. It only occurs, when I trigger update function constantly or sometimes randomly. When this error occurs my audio just turns off for a brief moment.

The logic behind my code. When program starts create function is invoked in the constructor creating Tone.sequence later on when I change/update track parameters i call update fuction, which calls loopprocessor with new/updated tracks. But when i trigger update which triggers loopprocessor function it runs into tone.sourcebuffer is either not set ir loaded. How can i work around this problem? My code:

import Tone from "tone";

export  function create(tracks, beatNotifier){
    const loop = new Tone.Sequence(
        loopProcessor(tracks, beatNotifier),
        [...new Array(16)].map((_, i) => i),
        "16n"
    );
    Tone.Transport.bpm.value = 120;
    Tone.Transport.start();
    return loop;
}

export function update(loop, tracks, beatNotifier){
    loop.callback = loopProcessor(tracks, beatNotifier);
    return loop;
}

function loopProcessor  (tracks, beatNotifier) {
    const urls = tracks.reduce((acc, {name}) => {
        return {...acc, [name]: `http://localhost:3000/src/sounds/${name}.[wav|wav]`};
    }, {});
    const keys = new Tone.Players(urls, {
        fadeOut: "64n"
    }).toMaster();
    return (time, index) => {
        beatNotifier(index);
        tracks.forEach(({name, vol, muted, note, beats}) => {
            if (beats[index]) {
                try {
                    var vel = Math.random() * 0.5 + 0.5;
                    keys
                        .get(name)
                        .start(time, 0, note, 0, vel);
                    keys
                        .get(name).volume.value = muted
                            ? -Infinity
                            : vol;
                } catch(e) {
                    console.log("error", e);
                }
            }
        });
    };
}

1

There are 1 best solutions below

0
On

I had this problem recently and found a solution that worked for my case.

Tone.js doesn't like it when you initialise an audio buffer inside a function (what you're doing when you call new Tone.Players inside loopprocessor).

To get around this at the top of your code declare a new global variable buffer1 = new Tone.Buffer(url1) for each url that you need. https://tonejs.github.io/docs/r13/Buffer

Then inside loopprocessor just replace urls with each buffer and a name tag and you shouldn't have any problems. So new Tone.Players({"name1": buffer1, "name2": buffer2, ...})