aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Pesch <inolen@gmail.com>2013-06-17 18:48:20 -0700
committerAnthony Pesch <inolen@gmail.com>2013-07-30 17:45:32 -0700
commit4088826095f06ae47a00544434d3db6a9fdf323e (patch)
tree8cb60e3e12938e43c8fd39436d4f43d8bbe9b770
parent9e0d03bde9e08842366e0fd17f1167cf2b4ecca2 (diff)
- fixed AudioBufferSourceNode start call, pass it an asbsolute time, not relative
- call updateSource when calling alGetSourcei
-rw-r--r--src/library_openal.js23
-rw-r--r--tests/openal_buffers.c54
-rwxr-xr-xtests/runner.py2
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):