chrisguttandin / audio-context-timers

A replacement for setInterval() and setTimeout() which works in unfocused windows.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Memory leak?

Avijobo opened this issue · comments

I am not a Javascript expert, but I wonder: each time this function below is called, a new audioBufferSourceNode is created. When will these nodes become garbage-collected? Isn't this a memory leak?

`const scheduleFunction = (id: number, delay: number, type: TTimerType) => {
    const now = performance.now();

    const audioBufferSourceNode = new AudioBufferSourceNode(MINIMAL_AUDIO_CONTEXT, { buffer: AUDIO_BUFFER });

    audioBufferSourceNode.onended = () => {
        const elapsedTime = performance.now() - now;

        if (elapsedTime >= delay) {
            callIntervalFunction(id, type);
        } else {
            scheduleFunction(id, delay - elapsedTime, type);
        }
    };
    audioBufferSourceNode.connect(MINIMAL_AUDIO_CONTEXT.destination);
    audioBufferSourceNode.start(Math.max(0, MINIMAL_AUDIO_CONTEXT.currentTime + delay / 1000 - SAMPLE_DURATION));
};`

I remember that this got me thinking the first time I heard of the AudioBufferSourceNode, too. Apparently the AudioBufferSourceNode as well as the OscillatorNode and the ConstantSourceNode are meant to be used only once. Their start() function can only be called once.

I can only speculate but I imagine it was created like that to simplify the communication between the main thread and the audio thread.

The browser should normally garbage collect any ended and unreachable AudioNode by itself but just to make sure everything got cleaned up correctly we could at least disconnect it manually. I will go ahead and add that.

Thanks a lot for reading the code thoroughly and creating this issue.