6

I'm trying to figure out a way to stop a web audio script processor node from running, without disconnecting it.

My initial thought was to just set the "onaudioprocess" to "null" to stop it, but when I do this I hear a really short loop of audio playing. My guess is that the audio buffer is not being cleared or something and it's repeatedly playing the same buffer.

I tried some additional techniques like first setting the buffer channel array values all to 0, then setting the "onaudioprocess" to "null", this still produced a looping slice of audio instead of silence.

I have some code like the below (coffeescript)

context = new webkitAudioContext()
scriptProcessor = context.createScriptProcessor()

scriptProcessor.onaudioprocess = (e)->
  outBufferL = e.outputBuffer.getChannelData(0)
  outBufferR = e.outputBuffer.getChannelData(1)
  i = 0
  while i < bufferSize
    outBufferL[i] = randomNoiseFunc()
    outBufferR[i] = randomNoiseFunc()
    i++
  return null
return null

Then when I want to stop it

stopFunc1: ->
  scriptProcessor.onaudioprocess = null

I also tried setting the buffer channel arrays to 0, then setting the callback to null

stopFunc2: ->
  scriptProcessor.onaudioprocess = (e)->
    outBufferL = e.outputBuffer.getChannelData(0)
    outBufferR = e.outputBuffer.getChannelData(1)
    i = 0
    while i < bufferSize
      outBufferL[i] = 0
      outBufferR[i] = 0
      i++
    scriptProcessor.onaudioprocess = null
    return null
  return null

Both techniques result in a slice of audio that loops really fast, instead of no audio.

Is there a way to do this correctly or am I just thinking about it wrong?

Any help greatly appreciated.

Cole Reed
  • 1,036
  • 1
  • 10
  • 12

1 Answers1

4

Maybe I'm misunderstanding...

But if you null out onaudioprocess, it won't stop playback immediately unless you just happen to hit it at the very end of the current buffer.

Let's say your bufferSize is 2048, and you happen to null out onaudioprocess half-way through the current buffer duration of 46ms (2048 / 44100 * 1000). You're still going to have the another 23ms of audio that's already been processed by your ScriptProcessor before you nulled it out.

Best bet is probably to throw a gain node into the path and just mute it on-demand.

Kevin Ennis
  • 14,226
  • 2
  • 43
  • 44
  • Yah, that seems to be the issue I'm running into. I was hoping there was an easy way to clear out the buffer before before setting the call back to `null`, but I have not found one. – Cole Reed Jul 15 '13 at 18:15
  • Well, you could call `stop()` on your `audioBufferSourceNode`. The `scriptProcessor` isn't really intended to be used as a mechanism for starting and stopping playback. If for some reason it's imperative that you use it that way, I guess you could reduce the `bufferSize` to cut down the amount of overhang after you null out `onaudioprocess`. – Kevin Ennis Jul 16 '13 at 00:36