diff options
-rw-r--r-- | src/library_openal.js | 195 | ||||
-rw-r--r-- | tests/openal_playback.cpp | 44 |
2 files changed, 235 insertions, 4 deletions
diff --git a/src/library_openal.js b/src/library_openal.js index 67481824..ac49fe95 100644 --- a/src/library_openal.js +++ b/src/library_openal.js @@ -5,6 +5,10 @@ var LibraryOpenAL = { $AL: { contexts: [], currentContext: null, + + stringCache: {}, + alcStringCache: {}, + QUEUE_INTERVAL: 25, QUEUE_LOOKAHEAD: 100, @@ -235,6 +239,42 @@ var LibraryOpenAL = { return _alGetError(); }, + alcGetIntegerv: function(device, param, size, data) { + if (size == 0 || !data) { + AL.currentContext.err = 0xA003 /* AL_INVALID_VALUE */; + return; + } + + switch(param) { + case 0x1000 /* ALC_MAJOR_VERSION */: + {{{ makeSetValue('data', '0', '1', 'i32') }}}; + break; + case 0x1001 /* ALC_MINOR_VERSION */: + {{{ makeSetValue('data', '0', '1', 'i32') }}}; + break; + case 0x1002 /* ALC_ATTRIBUTES_SIZE */: + if (!device) { + AL.currentContext.err = 0xA001 /* ALC_INVALID_DEVICE */; + return 0; + } + {{{ makeSetValue('data', '0', '1', 'i32') }}}; + break; + case 0x1003 /* ALC_ALL_ATTRIBUTES */: + if (!device) { + AL.currentContext.err = 0xA001 /* ALC_INVALID_DEVICE */; + return 0; + } + {{{ makeSetValue('data', '0', '0', 'i32') }}}; + break; + default: +#if OPENAL_DEBUG + console.log("alcGetIntegerv with param " + param + " not implemented yet"); +#endif + AL.currentContext.err = 0xA003 /* ALC_INVALID_ENUM */; + break; + } + }, + alDeleteSources: function(count, sources) { if (!AL.currentContext) { #if OPENAL_DEBUG @@ -334,6 +374,18 @@ var LibraryOpenAL = { } }, + alIsSource: function(sourceId) { + if (!AL.currentContext) { + return false; + } + + if (!AL.currentContext.src[sourceId - 1]) { + return false; + } else { + return true; + } + }, + alSourcei__deps: ['updateSource'], alSourcei: function(source, param, value) { if (!AL.currentContext) { @@ -691,6 +743,7 @@ var LibraryOpenAL = { } try { AL.currentContext.buf[buffer - 1] = AL.currentContext.ctx.createBuffer(channels, size / (bytes * channels), freq); + AL.currentContext.buf[buffer - 1].bytesPerSample = bytes; } catch (e) { AL.currentContext.err = 0xA003 /* AL_INVALID_VALUE */; return; @@ -715,6 +768,41 @@ var LibraryOpenAL = { } }, + alGetBufferi: function(buffer, param, value) + { + if (!AL.currentContext) { +#if OPENAL_DEBUG + console.error("alGetBufferi called without a valid context"); +#endif + return; + } + var buf = AL.currentContext.buf[buffer - 1]; + if (!buf) { +#if OPENAL_DEBUG + console.error("alGetBufferi called with an invalid buffer"); +#endif + AL.currentContext.err = 0xA001 /* AL_INVALID_NAME */; + return; + } + switch (param) { + case 0x2001 /* AL_FREQUENCY */: + {{{ makeSetValue('value', '0', 'buf.sampleRate', 'i32') }}}; + break; + case 0x2002 /* AL_BITS */: + {{{ makeSetValue('value', '0', 'buf.bytesPerSample * 8', 'i32') }}}; + break; + case 0x2003 /* AL_CHANNELS */: + {{{ makeSetValue('value', '0', 'buf.numberOfChannels', 'i32') }}}; + break; + case 0x2004 /* AL_SIZE */: + {{{ makeSetValue('value', '0', 'buf.length * buf.bytesPerSample * buf.numberOfChannels', 'i32') }}}; + break; + default: + AL.currentContext.err = 0xA002 /* AL_INVALID_ENUM */; + break; + } + }, + alSourcePlay__deps: ['setSourceState'], alSourcePlay: function(source) { if (!AL.currentContext) { @@ -1128,15 +1216,116 @@ var LibraryOpenAL = { }, alGetString: function(param) { - return allocate(intArrayFromString('NA'), 'i8', ALLOC_NORMAL); + if (AL.stringCache[param]) return AL.stringCache[param]; + var ret; + switch (param) { + case 0 /* AL_NO_ERROR */: + ret = 'No Error'; + break; + case 0xA001 /* AL_INVALID_NAME */: + ret = 'Invalid Name'; + break; + case 0xA002 /* AL_INVALID_ENUM */: + ret = 'Invalid Enum'; + break; + case 0xA003 /* AL_INVALID_VALUE */: + ret = 'Invalid Value'; + break; + case 0xA004 /* AL_INVALID_OPERATION */: + ret = 'Invalid Operation'; + break; + case 0xA005 /* AL_OUT_OF_MEMORY */: + ret = 'Out of Memory'; + break; + case 0xB001 /* AL_VENDOR */: + ret = 'Emscripten'; + break; + case 0xB002 /* AL_VERSION */: + ret = '1.1'; + break; + case 0xB003 /* AL_RENDERER */: + ret = 'WebAudio'; + break; + case 0xB004 /* AL_EXTENSIONS */: + ret = ''; + break; + default: + AL.currentContext.err = 0xA002 /* AL_INVALID_ENUM */; + return 0; + } + + ret = allocate(intArrayFromString(ret), 'i8', ALLOC_NORMAL); + + AL.stringCache[param] = ret; + + return ret; }, alGetProcAddress: function(fname) { return 0; }, - alcGetString: function(param) { - return allocate(intArrayFromString('NA'), 'i8', ALLOC_NORMAL); + alcGetString: function(device, param) { + if (AL.alcStringCache[param]) return AL.alcStringCache[param]; + var ret; + switch (param) { + case 0 /* ALC_NO_ERROR */: + ret = 'No Error'; + break; + case 0xA001 /* ALC_INVALID_DEVICE */: + ret = 'Invalid Device'; + break; + case 0xA002 /* ALC_INVALID_CONTEXT */: + ret = 'Invalid Context'; + break; + case 0xA003 /* ALC_INVALID_ENUM */: + ret = 'Invalid Enum'; + break; + case 0xA004 /* ALC_INVALID_VALUE */: + ret = 'Invalid Value'; + break; + case 0xA005 /* ALC_OUT_OF_MEMORY */: + ret = 'Out of Memory'; + break; + case 0x1004 /* ALC_DEFAULT_DEVICE_SPECIFIER */: + if (typeof(AudioContext) == "function" || + typeof(webkitAudioContext) == "function") { + ret = 'Device'; + } else { + return 0; + } + break; + case 0x1005 /* ALC_DEVICE_SPECIFIER */: + if (typeof(AudioContext) == "function" || + typeof(webkitAudioContext) == "function") { + ret = 'Device\0'; + } else { + ret = '\0'; + } + break; + case 0x311 /* ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER */: + return 0; + break; + case 0x310 /* ALC_CAPTURE_DEVICE_SPECIFIER */: + ret = '\0' + break; + case 0x1006 /* ALC_EXTENSIONS */: + if (!device) { + AL.currentContext.err = 0xA001 /* ALC_INVALID_DEVICE */; + return 0; + } + ret = ''; + break; + default: + AL.currentContext.err = 0xA003 /* ALC_INVALID_ENUM */; + return 0; + } + + ret = allocate(intArrayFromString(ret), 'i8', ALLOC_NORMAL); + + AL.alcStringCache[param] = ret; + + return ret; }, alcGetProcAddress: function(device, fname) { diff --git a/tests/openal_playback.cpp b/tests/openal_playback.cpp index 13d619e6..6a8dae38 100644 --- a/tests/openal_playback.cpp +++ b/tests/openal_playback.cpp @@ -3,11 +3,15 @@ #include <AL/al.h> #include <AL/alc.h> #include <assert.h> +#include <stdint.h> +#include <unistd.h> +#ifdef EMSCRIPTEN #include <emscripten.h> +#endif void playSource(void* arg) { - ALuint source = reinterpret_cast<ALuint>(arg); + ALuint source = static_cast<ALuint>(reinterpret_cast<intptr_t>(arg)); ALint state; alGetSourcei(source, AL_SOURCE_STATE, &state); assert(state == AL_PLAYING); @@ -21,15 +25,32 @@ void playSource(void* arg) alGetSourcei(source, AL_SOURCE_STATE, &state); assert(state == AL_STOPPED); +#ifdef EMSCRIPTEN int result = 1; REPORT_RESULT(); +#endif } int main() { + int major, minor; + alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &major); + alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &minor); + + assert(major == 1); + + printf("ALC version: %i.%i\n", major, minor); + printf("Default device: %s\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER)); + ALCdevice* device = alcOpenDevice(NULL); ALCcontext* context = alcCreateContext(device, NULL); alcMakeContextCurrent(context); + assert(alGetString(AL_VERSION)); + + printf("OpenAL version: %s\n", alGetString(AL_VERSION)); + printf("OpenAL vendor: %s\n", alGetString(AL_VENDOR)); + printf("OpenAL renderer: %s\n", alGetString(AL_RENDERER)); + ALfloat listenerPos[] = {0.0, 0.0, 0.0}; ALfloat listenerVel[] = {0.0, 0.0, 0.0}; ALfloat listenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0}; @@ -42,7 +63,11 @@ int main() { alGenBuffers(1, buffers); +#ifdef EMSCRIPTEN FILE* source = fopen("audio.wav", "rb"); +#else + FILE* source = fopen("sounds/audio.wav", "rb"); +#endif fseek(source, 0, SEEK_END); int size = ftell(source); fseek(source, 0, SEEK_SET); @@ -95,9 +120,21 @@ int main() { alBufferData(buffers[0], format, &buffer[offset], size - offset, frequency); + ALint val; + alGetBufferi(buffers[0], AL_FREQUENCY, &val); + assert(val == frequency); + alGetBufferi(buffers[0], AL_SIZE, &val); + assert(val == size - offset); + alGetBufferi(buffers[0], AL_BITS, &val); + assert(val == bits); + alGetBufferi(buffers[0], AL_CHANNELS, &val); + assert(val == channels); + ALuint sources[1]; alGenSources(1, sources); + assert(alIsSource(sources[0])); + alSourcei(sources[0], AL_BUFFER, buffers[0]); ALint state; @@ -109,7 +146,12 @@ int main() { alGetSourcei(sources[0], AL_SOURCE_STATE, &state); assert(state == AL_PLAYING); +#ifdef EMSCRIPTEN emscripten_async_call(playSource, reinterpret_cast<void*>(sources[0]), 700); +#else + usleep(700000); + playSource(reinterpret_cast<void*>(sources[0])); +#endif return 0; } |