- From: Jukka Jylänki <jujjyl@gmail.com>
- Date: Mon, 17 Jun 2013 11:16:36 +0300
- To: public-audio@w3.org
- Message-ID: <CA+6sJ-0cnd2-k4buq5DsX5fZdHPjUhjk4b0oha2b+v4N6Vkgmw@mail.gmail.com>
Hi, I authored a port of ScummVM over to Emscripten, and am currently implementing Web Audio API backend support to the Emscripten SDL audio API, to allow other browsers than Firefox to be able to play back audio as well. Existing SDL C/C++ applications utilize SDL audio in various sampling rates, and for example, ScummVM synthesizes 22kHz audio, whereas Chrome and Firefox both use 48kHz natively in the Web Audio graph. The way SDL works is that the C/C++ code code synthesizes the audio in small buffers of 1024-8192 samples (per sound channel) at a time. I hit an issue trying to manage the playback of these generated audio data. Currently I create an AudioBufferSourceNode for each buffer, fill it, and schedule it to be played back in appropriate time with AudioBufferSourceNode.start(when) call. This is problematic and produces glitching audio in both Firefox nightly and Chrome: http://clb.demon.fi/html5scummvm/tests2/monkey_webaudio_only.html (don't navigate to other pages from this page, they are _not_ test cases) https://dl.dropboxusercontent.com/u/40949268/emcc/bugs/webaudio_only_sdl_beep.html As a reference, try this in Firefox, which uses the Mozilla Audio Data API on Firefox (and Web Audio on Chrome): https://dl.dropboxusercontent.com/u/40949268/emcc/bugs/mozaudiodata_webaudio_sdl_beep.html In the above code, you can read the relevant source code by looking for a text string 'function _SDL_OpenAudio', which is a hand-written function - you can safely ignore the emscripten code. Alternatively, I tried using ScriptProcessorNode to schedule audio playback: http://clb.demon.fi/html5scummvm/tests2/monkey_webaudio_only_scriptprocessornode.html This produces glitch-free audio, but plays back with the wrong sampling rate. I have tried to find how to change the device playback rate, but it looks like this is not supported, am I correct? The question is: Since AudioBufferSourceNode.start(when) cannot guarantee sample-precise stitching of back-to-back buffers, and with the ScriptProcessorNode the playback rates don't match, how should I resolve this issue? I would prefer _not_ to have to write my own resampler just to go around an API limitation. Someone suggested using a secondary offline graph to resample, but that sounds like a complicated approach. I was more than slightly surprised to see that there is no 'buffer queueing' functionality in the Web Audio API. Other common sound APIs have this (see etc. OpenAL, XAudio2, DirectSound), and it allows applications to easily play back audio buffers while guaranteeing glitch-free stitching, and also allows filling with variable-sized buffers, e.g. in case of adaptive rate decoding audio. ScriptProcessorNode forces to a callback approach and limits to fixed buffer sizes. In addition to Emscripten SDL API (and other audio APIs on that platform), VOIP and multimedia playback applications commonly utilize this functionality. Is there a specific rationale why buffer queueing functionality, e.g. void AudioBufferSourceNode.startImmediatelyAfter(AudioBufferSourceNode predecessor); was left out from the spec? Thanks! Jukka
Received on Monday, 17 June 2013 12:42:10 UTC