diff options
Diffstat (limited to 'tests/openal_buffers.c')
-rw-r--r-- | tests/openal_buffers.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/tests/openal_buffers.c b/tests/openal_buffers.c new file mode 100644 index 00000000..6f51a685 --- /dev/null +++ b/tests/openal_buffers.c @@ -0,0 +1,187 @@ +#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 1470*10 + +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 iter(void *arg) { + ALuint buffer = 0; + ALint buffersProcessed = 0; + ALint buffersWereQueued = 0; + ALint buffersQueued = 0; + ALint state; + + alGetSourcei(source, AL_BUFFERS_PROCESSED, &buffersProcessed); + + 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; + } + + // Exit once we've processed the entire clip. + if (offset >= size) { +#ifdef EMSCRIPTEN + int result = 0; + REPORT_RESULT(); +#endif + exit(0); + } +} + +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. + // +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0, 0); +#else + while (1) { + iter(NULL); + usleep(16); + } +#endif +} |