1

when a user clicks on a button a sound is played , and if he clicks it again a new instance of that same sound is played .

i do that by connecting a new source node to the audio Context on every click.

now say that user clicks the button for 1 hour , does every source node that has finished playing gets deleted or it stays connected to the audio Context ?

soufiane yakoubi
  • 861
  • 11
  • 31
  • on your browser hit cntrl+shift+i to show dev tools --> Network -> perform your clicking and observe traffic --- then you are armed with skills to answer this and put you on the high road to other questions – Scott Stensland Mar 18 '19 at 17:14

2 Answers2

3

Here are the relevant specs:

The following behaviors provide a normative description of the conditions under which an AudioNode is alive, meaning that it MUST be retained in the graph by an implementation. Where these conditions do not apply, AudioNodes MAY be released by an implementation.

There are several types of references:

  1. A normal reference obeying normal garbage collection rules.

  2. A playing reference for AudioBufferSourceNodes, MediaElementAudioSourceNodes, MediaStreamAudioSourceNodes and OscillatorNodes. These nodes maintain a playing reference to themselves while they are currently playing.

  3. A connection reference which occurs if another AudioNode is connected to one or more of its inputs. Connections to a node’s AudioParams do not imply a connection reference.

  4. A tail-time reference which an AudioNode maintains on itself as long as it has any internal processing state which has not yet been emitted. For example, a ConvolverNode has a tail which continues to play even after receiving silent input (think about clapping your hands in a large concert hall and continuing to hear the sound reverberate throughout the hall). Some AudioNodes have this property. Please see details for specific nodes.

  5. MediaStreams keep a MediaStreamAudioSourceNode alive as long as the underlying MediaStreamTrack that is playing through the MediaStreamAudioSourceNode has not ended (as per [mediacapture-streams]).

  6. HTMLMediaElements keep their associated MediaElementAudioSourceNode alive as long as the HTMLMediaElement is in a state where audio could ever be played in the future.

So in the case of for instance, an AudioBufferSourceNode, since it has no input(3), no tail-time(4), is not linked to an external MediaStream(5) or MediaElement(6), if you don't keep any reference to the node in your js code(1), and that the Node has finished playing(2), then it can be removed from the graph, and then Garbage Collected.


Also note that most source nodes have a very little fingerprint anyway.

If once again we take AudioBufferSourceNodes as an example, then you have to understand that they don't duplicate the AudioBuffer, they just reference it.
So creating thousands of AudioBufferSourceNodes from the same AudioBuffer is fine.

However creating thousands of AudioBuffers from the same ArrayBuffer, or thousands of ArrayBuffers from the same file, or both is not fine at all, so be sure that when you are handling the click event all you do is create a new AudioBufferSourceNode, from a preexisting AudioBuffer.

Community
  • 1
  • 1
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • all i'm doing right now is calling a `play(buffer)` function that creates a source node with a referenced Audiobuffer , and then connecting it to the context . so if i do understand correctly , since the source node is not referenced anywhere it will get garbage collected because it has no reference anywhere in the code , right ? – soufiane yakoubi Mar 20 '19 at 12:01
  • 1
    Yes that's correct. Once it will have finished playing. – Kaiido Mar 20 '19 at 12:06
  • how about creating multiple Audio Contexts ? is that a bad practice ? i need to use two . – soufiane yakoubi Mar 20 '19 at 12:19
  • Yes, AudioContexts are hardly linked to hardware, so it is better to avoid having too much simultaneously, some browsers even did set up a limit on the number of simultaneous contexts you could have. But I can't think of any reason why you'd need more than one context in your own code. – Kaiido Mar 20 '19 at 14:05
  • i'm trying to practice the web audio API by doing a drum machine . so my problem was that if a user selects some previously recorded tracks , and then played them simultaneously , he can still use the pads , and the same goes for when he pauses those same tracks . after some research i finished with this idea of using two audio contexts , one for the pads and one for the recorded tracks , so i can pause them individually by calling `tracksContext.suspend()` and `tracksContext.resume()` , and `tracksContext.close()` to close the context when no track is playing . – soufiane yakoubi Mar 20 '19 at 17:30
  • Hmm interesting... I have to admit I never though of using context.suspend as a mean to **pause** everything in one go. That indeed sounds like a good use-case. But beware you might face some unexpected behavior. For instance, while fast testing it, I saw that Chrome does GC all unconnected nodes at *suspend*, this means that in [this fiddle](https://jsfiddle.net/1w79mfua/), where I used an AnalyserNode as a leaf, it got garbage collected at suspend. (the workaround thus being to connect the AnalyserNode to the destination through a mute node [here](https://jsfiddle.net/k7xd61h9/)). – Kaiido Mar 21 '19 at 01:37
  • in my case , i'm gonna use source nodes (one for each track) , some of them will be looping , maby connected to a delay/gain node ect .. , and finally connected to the destination . so i don't think i'll have that problem for now . – soufiane yakoubi Mar 21 '19 at 14:30
0

The BufferSourceNode won't be deleted if it's still connected to the audio context. You can check this by using the Firefox Web Audio dev tools, or installing the Audion Chrome extension.

You can add an onended function to the BufferSourceNode to disconnect it after it's used. Then, as long as nothing else has a reference to that buffer source node, it'll get cleaned up by the garbage collector.

Source: https://developer.mozilla.org/en-US/docs/Web/API/AudioScheduledSourceNode/onended

Anonymous
  • 171
  • 2
  • 10
  • 4
    The very reason we don't have back reference on connections was to allow Nodes to be Garbage Collected once we're done with them. I would be really surprised if they weren't. Maybe you should blame your Dev-tool / extension for keeping a reference to these nodes. – Kaiido Mar 20 '19 at 06:39