DSHCS
DSHCS

Reputation: 11

Shared Chrome AudioContext in Persistent Background Script

var audioContext = new window.AudioContext

chrome.runtime.onMessage.addListener(
  function(imageUrl, sender, sendResponse) {
    if (imageUrl != "") sound(523.251, 587.330) else sound(523.251, 493.883)
})

function sound(frequency1, frequency2) {

  soundDuration = 0.1

  var audioGain1 = audioContext.createGain()
  audioGain1.gain.value = 0.1
  audioGain1.connect(audioContext.destination)

  var audioGain2 = audioContext.createGain()
  audioGain2.gain.value = 0.1
  audioGain2.connect(audioContext.destination)

  var audioOscillator1 = audioContext.createOscillator()
  audioOscillator1.type = "sine"
  audioOscillator1.frequency.value = frequency1
  audioOscillator1.connect(audioGain1)

  var audioOscillator2 = audioContext.createOscillator()
  audioOscillator2.type = "sine"
  audioOscillator2.frequency.value = frequency2
  audioOscillator2.connect(audioGain2)

  audioOscillator1.start(0); audioOscillator1.stop(soundDuration)
  audioOscillator2.start(soundDuration); audioOscillator2.stop(soundDuration*2)
}

I am developing a Google Chrome extension (Version 47.0.2526.111 m). I ran into the problem were I exceed the AudioContext (AC) limit of six (6) with code running in the Web Page Content Script (CS). I rewrote the code to have the CS send a message to a persistent Background Script (BS). I defined the AudioContext in the body of the BS hoping that would only create one copy. Each time the CS sends a message to the BS, I want to play two (2) tones. I found I needed to create the GainNodes and OscillatorNodes in the BS .onMessage.addListener function in order to avoid the “one time use” behavior of these nodes.

When tested, no tones are generated. If I breakpoint the code and step through the .start() and .stop() statements, the tones are generated. If I let the code run free across the .start() and .stop() and breakpoint just after the .stop(), no tones. I suspected scope issues and tried the .createGain() and .createOscillator() creating local (var) and global (no var) variables, but that does not change the behavior.

If I put all the AC object creation in the listener function, it works fine, but I am back to running out of ACs.

The BS script code is above

Upvotes: 0

Views: 394

Answers (1)

DSHCS
DSHCS

Reputation: 11

I found the answer after reading a lot of web research. The issue seems to be the .start()/.stop() values being passed. I changed:

audioOscillator1.start(0); audioOscillator1.stop(soundDuration)

to

audioOscillator1.start(audioContext.currentTime + 0)
audioOscillator1.stop(audioContext.currentTime + soundDuration)

The code now works with the audiocontext in the script body (global) and does not hit the audioconext limit. The gain/oscillator nodes are still local to the onMessage function.

Upvotes: 1

Related Questions