http://codepen.io/superuntitled/pen/EjZOjw/?editors=001
I have a little web instrument (see link above) that has a memory leak, and I am unsure how to plug it.
The following function is called when an element is hovered over (there are a couple hundred of these).
function tone(id, freq, tonelength) {
gainNodes.id = audioCtx.createGain();
osc.id = audioCtx.createOscillator();
osc.id.connect(gainNodes.id);
// set frequency and gain
osc.id.frequency.value = freq;
osc.id.start(0);
gainNodes.id.connect(audioCtx.destination);
gainNodes.id.gain.linearRampToValueAtTime(.1, audioCtx.currentTime);
gainNodes.id.gain.linearRampToValueAtTime(0, audioCtx.currentTime + parseFloat(tonelength));
}
I think that duplicate oscillators are being created, but am not sure how to check if this is the case, or how to avoid it.
I have a feeling I should check to see if the oscillator already exists, and just run the gain, but I am not sure how to do that.
I have tried to stop the oscillator after it's duration, but this does not seem to stop the leak: http://codepen.io/superuntitled/pen/rVmqYX?editors=001
osc.id.stop(audioCtx.currentTime + parseFloat(tonelength));
Any thoughts on how this could be done?
The thing with
osc.id
is a little weird, since you're settingid
as a property name instead ofosc[ id ]
– but leaving that part aside, you'd want to add this to the bottom of yourtone()
function:That basically says "Stop playing after 2 seconds, and when you're done, disconnect yourself from the AudioContext".
If
id
was dynamically assigned toosc
(e.g.osc[ id ]
), then you'd likely also need todelete osc[ id ]
– but that seems to just be getting overridden each timetone()
is called with the way you have it now – so the old oscillator should become eligible for garbage collection.The reason for the
current
variable is that by the timeonended
fires,osc.id
will likely have been reassigned – so you need a reference to the original oscillator.Hope that helps.