1

I have my 8 bit computer emulator written in JavaScript, it uses WebAudio and createScriptProcessor to genarate sound based on the internal state of the "virtual" sound chip emulated (even digital samples, so it's not webaudio oscillator based solution). It works nicely on Chrome, but not on Firefox, there is no sound at all with Firefox (tested with versions 30 and 31). The strange thing: it seems the function given by the onaudioprocess is not called at all on Firefox, but it is on Chrome. I've tested it with putting a console.log() into that callback function, but not a single line produced by that is displayed within the JavaScript console. The minimal skeleton of my solution I tested then separately:

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioCtx = new AudioContext();
/* comment: see later */
var audioNode = audioCtx.createScriptProcessor(4096, 2, 2);
audioNode.connect(audioCtx.destination);
audioNode.onaudioprocess = function (e) { console.log("process: " + e.toString()); };

Of course it does not produce too much sound, but it should print messages onto the javascript console periodically (but for sure, at least once ...). And indeed it does, on both of firefox (!!) and chrome. Now the odd thing what I can't understand: the very same scheme is used in my emulator but there, the callback function registered with audioNode.onaudioprocess is not called ever. I can't imagine why, because it works in a simple example like the one above. But as far as I can see, this causes the situation that my code does not produce any sound on Firefox. The only difference between the code above and my emulator, that the lines after the "comment" is given separately, when you start the emulator with the "run!" button, the parts before is executed on loading the emulator (page).

My not so precise question: what kind of problems can cause this? If that the test code fragment above works, and the very same is used in my emulator, I can't understand what can be the difference. My emulator uses setTimeout() for the timing of the speed of the emulated machine, can it mess the onaudioprocess up somehow?

UPDATE, WORKAROUND

It seems the solution is to put new AudioContext() at the same part where creating audioNode and .connect() is done, then it works. However I don't understand why it is a problem: audioCtx was stored in the global variable scope (as I've read it can be a problem to have some garbage collection messing up webaudio a bit). Does anybody have any idea what is the reason of this behaviour?

Thanks a lot in advance, any feedback is welcome!

LGB
  • 728
  • 1
  • 9
  • 20
  • Would you mind giving me a link to the actual code? – padenot Jul 23 '14 at 12:56
  • @padenot surely, http://ep.lgb.hu/jsep/audio.html with some notes, but be careful, the source is extremely ugly, I learnt JavaScript on writing this started with almost the hello world program :) – LGB Jul 23 '14 at 14:01
  • Note that you've got an invalid left-hand even in Chrome. Check out the developer tools console for errors. – cwilso Jul 23 '14 at 14:48
  • @cwilso Hmm I can't see any ... Can you tell which file, which line? For me, no error is shown by firefox or chrome console ... :( – LGB Jul 23 '14 at 19:03
  • I've read several problems like garbage collection problem that the processor function is garbage collected, so it should be stored in the global scope etc, but as far as I see I am not affected with these problems. – LGB Jul 25 '14 at 08:40
  • Interesting, I think I found the problem, but I don't know the "why": if I put new AudioContext at the same place, it works! Even though new AudioContext() is stored in a global variable ...Is it not allowed to create my audio context and use its value later? – LGB Jul 25 '14 at 09:04
  • When I go to http://ep.lgb.hu/jsep/demo.new/?sound=yes in Chrome Canary, OSX, I get invalid left-hand side in assignment at z80_ops_full.js:33. – cwilso Jul 25 '14 at 17:27
  • 1
    yeah, you should be able to cache AudioContexts. As long as you're not using too many of them. – cwilso Jul 25 '14 at 17:28
  • Hmm, even with all audio init moved to _one_ function which is works if called from the event handler of a button click for example, it does not work again, if page onload handler calls it! It seems (for me) that firefox implements a policy like I've read about Apple: no sound till some user interaction triggers the sound to avoid having pages generating audio without the will of the user. Can it be?? – LGB Jul 26 '14 at 07:22

0 Answers0