diff options
Diffstat (limited to 'tests/openal_buffers.c')
-rw-r--r-- | tests/openal_buffers.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/tests/openal_buffers.c b/tests/openal_buffers.c new file mode 100644 index 00000000..f89a5791 --- /dev/null +++ b/tests/openal_buffers.c @@ -0,0 +1,173 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#ifdef EMSCRIPTEN +#include <emscripten.h> +#include <AL/al.h> +#include <AL/alc.h> +#else +#include "../system/include/AL/al.h" +#include "../system/include/AL/alc.h" +#endif + +#define NUM_BUFFERS 4 +#define BUFFER_SIZE 1024*8 + +ALCdevice* device = NULL; +ALCcontext* context = NULL; + +// Audio source state. +unsigned char* data = NULL; +unsigned int size = 0; +unsigned int offset = 0; +unsigned int channels = 0; +unsigned int frequency = 0; +unsigned int bits = 0; +ALenum format = 0; +ALuint source = 0; + +void cycle(void *arg) { + ALuint buffer = 0; + ALint numBuffers = 0; + + alGetSourcei(source, AL_BUFFERS_PROCESSED, &numBuffers); + + while (offset < size && numBuffers--) { + alSourceUnqueueBuffers(source, 1, &buffer); + int len = size - offset; + if (len > BUFFER_SIZE) { + len = BUFFER_SIZE; + } + alBufferData(buffer, format, &data[offset], len, frequency); + alSourceQueueBuffers(source, 1, &buffer); + assert(alGetError() == AL_NO_ERROR); + + offset += len; + } + + // Exit once we've processed the entire clip. + if (offset >= size) { +#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 + } +} + +int main(int argc, char* argv[]) { + // + // Setup the AL context. + // + device = alcOpenDevice(NULL); + context = alcCreateContext(device, NULL); + alcMakeContextCurrent(context); + + // + // Read in the audio sample. + // +#ifdef EMSCRIPTEN + FILE* fp = fopen("the_entertainer.wav", "rb"); +#else + FILE* fp = fopen("sounds/the_entertainer.wav", "rb"); +#endif + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + data = (unsigned char*)malloc(size); + fread(data, size, 1, fp); + fclose(fp); + + offset = 12; // ignore the RIFF header + offset += 8; // ignore the fmt header + offset += 2; // ignore the format type + + channels = data[offset + 1] << 8; + channels |= data[offset]; + offset += 2; + printf("Channels: %u\n", channels); + + frequency = data[offset + 3] << 24; + frequency |= data[offset + 2] << 16; + frequency |= data[offset + 1] << 8; + frequency |= data[offset]; + offset += 4; + printf("Frequency: %u\n", frequency); + + offset += 6; // ignore block size and bps + + bits = data[offset + 1] << 8; + bits |= data[offset]; + offset += 2; + printf("Bits: %u\n", bits); + + format = 0; + if (bits == 8) { + if (channels == 1) { + format = AL_FORMAT_MONO8; + } else if (channels == 2) { + format = AL_FORMAT_STEREO8; + } + } else if (bits == 16) { + if (channels == 1) { + format = AL_FORMAT_MONO16; + } else if (channels == 2) { + format = AL_FORMAT_STEREO16; + } + } + offset += 8; // ignore the data chunk + + // + // Seed the buffers with some initial data. + // + ALuint buffers[NUM_BUFFERS]; + alGenBuffers(NUM_BUFFERS, buffers); + alGenSources(1, &source); + + ALint numBuffers = 0; + while (numBuffers < NUM_BUFFERS && offset < size) { + int len = size - offset; + if (len > BUFFER_SIZE) { + len = BUFFER_SIZE; + } + + alBufferData(buffers[numBuffers], format, &data[offset], len, frequency); + alSourceQueueBuffers(source, 1, &buffers[numBuffers]); + assert(alGetError() == AL_NO_ERROR); + + offset += len; + numBuffers++; + } + + // + // Start playing the source. + // + alSourcePlay(source); + + ALint state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + assert(state == AL_PLAYING); + + alGetSourcei(source, AL_BUFFERS_QUEUED, &numBuffers); + assert(numBuffers == NUM_BUFFERS); + + // + // Cycle and refill the buffers until we're done. + // +#ifdef EMSCRIPTEN + emscripten_async_call(cycle, NULL, 10); +#else + cycle(); +#endif +} |