diff options
author | Anthony Pesch <inolen@gmail.com> | 2013-06-17 18:48:20 -0700 |
---|---|---|
committer | Anthony Pesch <inolen@gmail.com> | 2013-07-30 17:45:32 -0700 |
commit | 4088826095f06ae47a00544434d3db6a9fdf323e (patch) | |
tree | 8cb60e3e12938e43c8fd39436d4f43d8bbe9b770 | |
parent | 9e0d03bde9e08842366e0fd17f1167cf2b4ecca2 (diff) |
- fixed AudioBufferSourceNode start call, pass it an asbsolute time, not relative
- call updateSource when calling alGetSourcei
-rw-r--r-- | src/library_openal.js | 23 | ||||
-rw-r--r-- | tests/openal_buffers.c | 54 | ||||
-rwxr-xr-x | tests/runner.py | 2 |
3 files changed, 52 insertions, 27 deletions
diff --git a/src/library_openal.js b/src/library_openal.js index bcbe6d64..d2516559 100644 --- a/src/library_openal.js +++ b/src/library_openal.js @@ -136,18 +136,16 @@ var LibraryOpenAL = { } // Process all buffers that'll be played before the next tick. else if (startOffset < (AL.QUEUE_LOOKAHEAD / 1000) && !entry.src) { - // If the offset is positive, we need to delay playing the sound that amount. - var when = Math.max(startOffset, 0); - // If the offset is negative, we need to play immediately, offset by its absolute value (print warning?). + // If the start offset is negative, we need to offset the actual buffer. var offset = Math.abs(Math.min(startOffset, 0)); entry.src = AL.currentContext.ctx.createBufferSource(); entry.src.buffer = entry.buffer; entry.src.connect(src.gain); - entry.src.start(when, offset); + entry.src.start(startTime, offset); #if OPENAL_DEBUG - console.log('updateSource queuing buffer ' + i + ' for source ' + idx + ' in ' + when + ' (starting at ' + offset + ')'); + console.log('updateSource queuing buffer ' + i + ' for source ' + idx + ' at ' + startTime + ' (offset by ' + offset + ')'); #endif } @@ -465,6 +463,7 @@ var LibraryOpenAL = { } }, + alSourcefv__deps: ['alSource3f'], alSourcefv: function(source, param, value) { _alSource3f(source, param, {{{ makeGetValue('value', '0', 'float') }}}, @@ -509,6 +508,7 @@ var LibraryOpenAL = { _updateSource(src); }, + alSourceUnqueueBuffers__deps: ["updateSource"], alSourceUnqueueBuffers: function(source, count, buffers) { if (!AL.currentContext) { #if OPENAL_DEBUG @@ -538,12 +538,13 @@ var LibraryOpenAL = { var b = AL.currentContext.buf[j]; if (b && b == entry.buffer) { {{{ makeSetValue('buffers', 'i*4', 'j+1', 'i32') }}}; - src.buffer = null; break; } } src.buffersPlayed--; } + + _updateSource(src); }, alDeleteBuffers: function(count, buffers) @@ -729,6 +730,7 @@ var LibraryOpenAL = { _setSourceState(src, 0x1013 /* AL_PAUSED */); }, + alGetSourcei__deps: ['updateSource'], alGetSourcei: function(source, param, value) { if (!AL.currentContext) { #if OPENAL_DEBUG @@ -745,6 +747,15 @@ var LibraryOpenAL = { AL.currentContext.err = 0xA001 /* AL_INVALID_NAME */; return; } + + // Being that we have no way to receive end events from buffer nodes, + // we currently proccess and update a source's buffer queue every + // ~QUEUE_INTERVAL milliseconds. However, this interval is not precise, + // so we also forcefully update the source when alGetSourcei is queried + // to aid in the common scenario of application calling alGetSourcei(AL_BUFFERS_PROCESSED) + // to recycle buffers. + _updateSource(src); + switch (param) { case 0x202 /* AL_SOURCE_RELATIVE */: {{{ makeSetValue('value', '0', 'src.panner ? 1 : 0', 'i32') }}}; diff --git a/tests/openal_buffers.c b/tests/openal_buffers.c index f89a5791..6f51a685 100644 --- a/tests/openal_buffers.c +++ b/tests/openal_buffers.c @@ -11,7 +11,7 @@ #endif #define NUM_BUFFERS 4 -#define BUFFER_SIZE 1024*8 +#define BUFFER_SIZE 1470*10 ALCdevice* device = NULL; ALCcontext* context = NULL; @@ -26,22 +26,43 @@ unsigned int bits = 0; ALenum format = 0; ALuint source = 0; -void cycle(void *arg) { +void iter(void *arg) { ALuint buffer = 0; - ALint numBuffers = 0; + ALint buffersProcessed = 0; + ALint buffersWereQueued = 0; + ALint buffersQueued = 0; + ALint state; - alGetSourcei(source, AL_BUFFERS_PROCESSED, &numBuffers); + alGetSourcei(source, AL_BUFFERS_PROCESSED, &buffersProcessed); - while (offset < size && numBuffers--) { + while (offset < size && buffersProcessed--) { + // unqueue the old buffer and validate the queue length + alGetSourcei(source, AL_BUFFERS_QUEUED, &buffersWereQueued); alSourceUnqueueBuffers(source, 1, &buffer); + + assert(alGetError() == AL_NO_ERROR); int len = size - offset; if (len > BUFFER_SIZE) { len = BUFFER_SIZE; } + + alGetSourcei(source, AL_BUFFERS_QUEUED, &buffersQueued); + assert(buffersQueued == buffersWereQueued - 1); + + // queue the new buffer and validate the queue length + buffersWereQueued = buffersQueued; alBufferData(buffer, format, &data[offset], len, frequency); + alSourceQueueBuffers(source, 1, &buffer); assert(alGetError() == AL_NO_ERROR); + alGetSourcei(source, AL_BUFFERS_QUEUED, &buffersQueued); + assert(buffersQueued == buffersWereQueued + 1); + + // make sure it's still playing + alGetSourcei(source, AL_SOURCE_STATE, &state); + assert(state == AL_PLAYING); + offset += len; } @@ -50,18 +71,8 @@ void cycle(void *arg) { #ifdef EMSCRIPTEN int result = 0; REPORT_RESULT(); -#else - exit(0); -#endif - } - // Give the JS thread a few ms to breathe. - else { -#ifdef EMSCRIPTEN - emscripten_async_call(cycle, NULL, 10); -#else - usleep(10); - cycle(); #endif + exit(0); } } @@ -165,9 +176,12 @@ int main(int argc, char* argv[]) { // // Cycle and refill the buffers until we're done. // -#ifdef EMSCRIPTEN - emscripten_async_call(cycle, NULL, 10); -#else - cycle(); +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0, 0); +#else + while (1) { + iter(NULL); + usleep(16); + } #endif } diff --git a/tests/runner.py b/tests/runner.py index 1781980a..2627d113 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -13252,7 +13252,7 @@ Press any key to continue.''' shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.wav'), os.path.join(self.get_dir(), 'the_entertainer.wav')) open(os.path.join(self.get_dir(), 'openal_buffers.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'openal_buffers.c')).read())) - Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'openal_buffers.c'), '--preload-file', 'the_entertainer.wav', '-o', 'page.html']).communicate() + Popen([PYTHON, EMCC, '-O0', os.path.join(self.get_dir(), 'openal_buffers.c'), '--preload-file', 'the_entertainer.wav', '-o', 'page.html']).communicate() self.run_browser('page.html', '', '/report_result?0') def test_glfw(self): |