diff -r 228757f6c54d -r fececcbc2189 openalbridge/openalbridge.c --- a/openalbridge/openalbridge.c Wed Oct 14 16:30:41 2009 +0000 +++ b/openalbridge/openalbridge.c Wed Oct 14 22:12:02 2009 +0000 @@ -1,6 +1,7 @@ /* * OpenAL Bridge - a simple portable library for OpenAL interface - * Copyright (c) 2009 Vittorio Giovara + * Copyright (c) 2009 Vittorio Giovara , + * Mario Liebisch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -19,480 +20,594 @@ #include "openalbridge.h" -#ifdef __CPLUSPLUS -extern "C" { -#endif - - /*Sources are points emitting sound*/ - ALuint *Sources; - /*Buffers hold sound data*/ - ALuint *Buffers; - /*index for Sources and Buffers*/ - ALuint globalindex, globalsize, increment; - - ALboolean openalReady = AL_FALSE; +char *prog; + +/*Buffers hold sound data*/ +ALuint *Buffers; +/*index for Sources and Buffers*/ +ALuint globalindex, globalsize, increment; + +//null vector +const ALfloat NV[] = {0.0f, 0.0f, 0.0f}; +//listener orientation +const ALfloat LO[] = {0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f}; + +SSound_t aSounds[MAX_SOUNDS]; +int iNumSounds = 0; +char oalbReady = 0; + +ALCcontext *context; +ALCdevice *device; +ALuint sources[MAX_SOURCES]; + + + + + +/** + * const char oalb_init (const char* programname, const char usehardware) + * + * ARGUMENTS + * programname [const char*]: name of the program invoking OpenAL + * usehardware [const char] : flag to enable audio hardware acceleration + * DESCRIPTION + * + * RETURN + * 1 success + * 2 error + */ + +char oalb_init (const char* programname, const char usehardware) { + prog = (char *) programname; - ALboolean openal_close (void) { - /*Stop all sounds, deallocate all memory and close OpenAL */ - ALCcontext *context; - ALCdevice *device; - - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - alSourceStopv (globalsize, Sources); - alDeleteSources (globalsize, Sources); - alDeleteBuffers (globalsize, Buffers); - - free(Sources); - free(Buffers); - - context = alcGetCurrentContext(); - device = alcGetContextsDevice(context); - - alcMakeContextCurrent(NULL); - alcDestroyContext(context); - alcCloseDevice(device); - - openalReady = AL_FALSE; - - return AL_TRUE; + if (oalbReady == AL_TRUE) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL already initialized", prog); + return AL_FALSE; } - ALboolean openal_ready(void) { - return openalReady; +#ifdef _WIN32 + /* Hardware acceleration is broken on some windows card*/ + if (usehardware != 0) + device = alcOpenDevice(NULL); + else + { + device = alcOpenDevice("Generic Software"); + if(!device) + { + err_msg("(%s) WARN - Failed to open software device", prog); + device = alcOpenDevice(NULL); + } + } +#else + /*always hardware for UNIX systems*/ + device = alcOpenDevice(NULL); +#endif + + if (device == NULL) { + errno = ENODEV; + err_ret("(%s) WARN - Failed to open sound device", prog); + return AL_FALSE; } - ALboolean openal_init(char* programname, ALboolean usehardware, uint32_t memorysize) { - /*Initialize an OpenAL contex and allocate memory space for data and buffers*/ - ALCcontext *context; - ALCdevice *device; - const ALCchar *default_device; - - prog = programname; - - /*Position of the listener*/ - ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 }; - /*Velocity of the listener*/ - ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 }; - /*Orientation of the listener. (first 3 elements are "at", second 3 are "up")*/ - ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; - - if (openalReady == AL_TRUE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL already initialized", prog); - return AL_FALSE; - } - - if (usehardware == AL_TRUE) - device = alcOpenDevice(NULL); - else - device = alcOpenDevice("Generic Software"); - - if (device == NULL) { - errno = ENODEV; - err_ret("(%s) WARN - Failed to open sound device", prog); - return AL_FALSE; - } - err_msg("(%s) INFO - Output device: %s", prog, alcGetString(device, ALC_DEVICE_SPECIFIER)); - - context = alcCreateContext(device, NULL); - alcMakeContextCurrent(context); - alcProcessContext(context); - - if (AlGetError("(%s) WARN - Failed to create a new contex") != AL_TRUE) - return AL_FALSE; - - /*allocate memory space for buffers and sources*/ - if (memorysize == 0) - globalsize = 50; - else - globalsize = memorysize; - increment = globalsize; - - Buffers = (ALuint*) Malloc(sizeof(ALuint)*globalsize); - Sources = (ALuint*) Malloc(sizeof(ALuint)*globalsize); - - /*set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation*/ - alListenerf (AL_GAIN, 1.0f ); - alListenerfv(AL_POSITION, ListenerPos); - alListenerfv(AL_VELOCITY, ListenerVel); - alListenerfv(AL_ORIENTATION, ListenerOri); - - if (AlGetError("(%s) WARN - Failed to set Listener properties") != AL_TRUE) - return AL_FALSE; - - openalReady = AL_TRUE; - - alGetError(); /* clear any AL errors beforehand */ - return AL_TRUE; - } + err_msg("(%s) INFO - Using OpenAL device: %s", prog, alcGetString(device, ALC_DEVICE_SPECIFIER)); + context = alcCreateContext(device, NULL); + alcMakeContextCurrent(context); - ALboolean helper_realloc (void) { - /*expands allocated memory when loading more sound files than expected*/ - int oldsize = globalsize; - globalsize += increment; - -#ifdef DEBUG - err_msg("(%s) INFO - Realloc in process from %d to %d\n", prog, oldsize, globalsize); -#endif - - Buffers = (ALuint*) Realloc(Buffers, sizeof(ALuint)*globalsize); - Sources = (ALuint*) Realloc(Sources, sizeof(ALuint)*globalsize); - - return AL_TRUE; - } + if (AlGetError("(%s) WARN - Failed to create a new contex") != AL_TRUE) + return AL_FALSE; - ALint openal_loadfile (const char *filename){ - /*Open a file, load into memory and allocate the Source buffer for playing*/ - ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; /*Position of the source sound*/ - ALfloat SourceVel[] = { 0.0, 0.0, 0.0 }; /*Velocity of the source sound*/ - ALenum format; - ALsizei bitsize, freq; - char *data; - uint32_t fileformat; - ALenum error; - FILE *fp; - - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - /*when the buffers are all used, we can expand memory to accept new files*/ - if (globalindex == globalsize) - helper_realloc(); - - /*detect the file format, as written in the first 4 bytes of the header*/ - fp = Fopen (filename, "rb"); - - if (fp == NULL) - return -1; - - error = fread (&fileformat, sizeof(uint32_t), 1, fp); - fclose (fp); - - if (error < 0) { - errno = EIO; - err_ret("(%s) ERROR - File %s is too short", prog, filename); - return -2; - } - - /*prepare the buffer to receive data*/ - alGenBuffers(1, &Buffers[globalindex]); - - if (AlGetError("(%s) ERROR - Failed to allocate memory for buffers") != AL_TRUE) - return -3; - - /*prepare the source to emit sound*/ - alGenSources(1, &Sources[globalindex]); - - if (AlGetError("(%s) ERROR - Failed to allocate memory for sources") != AL_TRUE) - return -4; - - - switch (ENDIAN_BIG_32(fileformat)) { - case OGG_FILE_FORMAT: - error = load_oggvorbis (filename, &format, &data, &bitsize, &freq); - break; - case WAV_FILE_FORMAT: - error = load_wavpcm (filename, &format, &data, &bitsize, &freq); - break; - default: - errno = EINVAL; - err_ret ("(%s) ERROR - File format (%08X) not supported", prog, ENDIAN_BIG_32(fileformat)); - return -5; - break; - } - - - /*copy pcm data in one buffer*/ - alBufferData(Buffers[globalindex], format, data, bitsize, freq); - free(data); /*deallocate data to save memory*/ - - if (AlGetError("(%s) ERROR - Failed to write data to buffers") != AL_TRUE) - return -6; - - /*set source properties that it will use when it's in playback*/ - alSourcei (Sources[globalindex], AL_BUFFER, Buffers[globalindex] ); - alSourcef (Sources[globalindex], AL_PITCH, 1.0f ); - alSourcef (Sources[globalindex], AL_GAIN, 1.0f ); - alSourcefv(Sources[globalindex], AL_POSITION, SourcePos ); - alSourcefv(Sources[globalindex], AL_VELOCITY, SourceVel ); - alSourcei (Sources[globalindex], AL_LOOPING, 0 ); - - if (AlGetError("(%s) ERROR - Failed to set Source properties") != AL_TRUE) - return -7; - - alGetError(); /* clear any AL errors beforehand */ - - /*returns the index of the source you just loaded, increments it and exits*/ - return globalindex++; + /*set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation*/ + alListenerf (AL_GAIN, 1.0f); + alListenerfv(AL_POSITION, NV); + alListenerfv(AL_VELOCITY, NV); + alListenerfv(AL_ORIENTATION, LO); + + alcProcessContext(context); + + if (AlGetError("(%s) WARN - Failed to set Listener properties") != AL_TRUE) + return AL_FALSE; + + alGenSources(MAX_SOURCES, sources); + + oalbReady = AL_TRUE; + + alGetError(); /* clear any AL errors beforehand */ + return AL_TRUE; +} + + +/** + * void oalb_close(void) + * + * ARGUMENTS + * - + * DESCRIPTION + * + * RETURN + * - + */ + +void oalb_close(void) { + /*Stop all sounds, deallocate all memory and close OpenAL */ + int i; + + if (oalbReady == 0) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return; + } + + for(i = 0; i < iNumSounds; i++) { + SSound_stop(&aSounds[i]); + SSound_close(&aSounds[i]); + } + + alSourceStopv (MAX_SOURCES, sources); + alDeleteSources (MAX_SOURCES, sources); + + alcMakeContextCurrent(NULL); + alcDestroyContext(context); + alcCloseDevice(device); + + oalbReady = 0; + + return; +} + +char oalb_ready(void) { + return oalbReady; +} + +/** + * const int32_t oalb_loadfile (const char *filename) + * + * ARGUMENTS + * - + * DESCRIPTION + * + * RETURN + * - + */ + +int32_t oalb_loadfile (const char *filename) { + int i; + + if (oalbReady == 0) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return -1; + } + + if(iNumSounds == MAX_SOUNDS) { + err_msg("(%s) WARN - Maximum number of sound samples reached", prog); + return -3; } - ALboolean openal_toggleloop (uint32_t index){ - /*Set or unset looping mode*/ - ALint loop; - - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - if (index >= globalsize) { - errno = EINVAL; - err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); - return AL_FALSE; - } - - alGetSourcei (Sources[index], AL_LOOPING, &loop); - alSourcei (Sources[index], AL_LOOPING, !((uint8_t) loop) & 0x00000001); - if (AlGetError("(%s) ERROR - Failed to get or set loop property") != AL_TRUE) - return AL_FALSE; - - alGetError(); /* clear any AL errors beforehand */ - - return AL_TRUE; + for(i = 0; i < iNumSounds; i++) + if(strcmp(aSounds[i].Filename, filename) == 0) + return i; + + if(SSound_load(&aSounds[iNumSounds], filename)) + return iNumSounds++; + else + return -2; + +} + +/* + ALboolean openal_toggleloop (uint32_t index){ + /*Set or unset looping mode + ALint loop; + + if (oalbReady == AL_FALSE) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return AL_FALSE; + } + + if (index >= globalsize) { + errno = EINVAL; + err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); + return AL_FALSE; + } + + alGetSourcei (Sources[index], AL_LOOPING, &loop); + alSourcei (Sources[index], AL_LOOPING, !((uint8_t) loop) & 0x00000001); + if (AlGetError("(%s) ERROR - Failed to get or set loop property") != AL_TRUE) + return AL_FALSE; + + alGetError(); /* clear any AL errors beforehand + + return AL_TRUE; + } + */ + +void oalb_setvolume (const uint32_t iIndex, const char cPercentage) { + if (oalbReady == 0) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return; + } + + /*Set volume for sound number index*/ + if(iIndex < 0 || iIndex >= iNumSounds) { + errno = EINVAL; + err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); + return; + } + + if(cPercentage > 100) + SSound_volume(&aSounds[iIndex], 1.0f); + else + SSound_volume(&aSounds[iIndex], cPercentage / 100.0f); + + if (AlGetError2("(%s) ERROR - Failed to set volume for sound %d\n", iIndex) != AL_TRUE) + return; + + alGetError(); /* clear any AL errors beforehand */ + + return; +} + + +void oalb_setglobalvolume (const char cPercentage) { + if (oalbReady == 0) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return; } + /*Set volume for all sounds*/ + if(cPercentage > 100) + alListenerf (AL_GAIN, 1.0f); + else + alListenerf (AL_GAIN, cPercentage / 100.0f); - ALboolean openal_setvolume (uint32_t index, uint8_t percentage) { - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - /*Set volume for sound number index*/ - if (index >= globalsize) { - errno = EINVAL; - err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); - return AL_FALSE; - } - - if (percentage > 100) - percentage = 100; - alSourcef (Sources[index], AL_GAIN, (float) percentage/100.0f); - if (AlGetError2("(%s) ERROR - Failed to set volume for sound %d\n", index) != AL_TRUE) - return AL_FALSE; - - alGetError(); /* clear any AL errors beforehand */ - - return AL_TRUE; + if (AlGetError("(%s) ERROR - Failed to set global volume") != AL_TRUE) + return; + + alGetError(); /* clear any AL errors beforehand */ + + return; +} + +/* + ALboolean openal_togglemute () { + /*Mute or unmute sound + ALfloat mute; + + if (oalbReady == AL_FALSE) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return AL_FALSE; + } + + alGetListenerf (AL_GAIN, &mute); + if (mute > 0) + mute = 0; + else + mute = 1.0; + alListenerf (AL_GAIN, mute); + if (AlGetError("(%s) ERROR - Failed to set mute property") != AL_TRUE) + return AL_FALSE; + + alGetError(); /* clear any AL errors beforehand + + return AL_TRUE; + } + + + ALboolean openal_fade (uint32_t index, uint16_t quantity, ALboolean direction) { + /*Fade in or out by calling a helper thread + #ifndef _WIN32 + pthread_t thread; + #else + HANDLE Thread; + DWORD threadID; + #endif + fade_t *fade; + + if (oalbReady == AL_FALSE) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return AL_FALSE; + } + + fade = (fade_t*) Malloc(sizeof(fade_t)); + fade->index = index; + fade->quantity = quantity; + + if (index >= globalsize) { + errno = EINVAL; + err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); + return AL_FALSE; + } + + switch (direction) { + case FADE_IN: + #ifndef _WIN32 + pthread_create(&thread, NULL, helper_fadein, (void*) fade); + #else + Thread = _beginthread(&helper_fadein, 0, (void*) fade); + #endif + break; + case FADE_OUT: + #ifndef _WIN32 + pthread_create(&thread, NULL, helper_fadeout, (void*) fade); + #else + Thread = _beginthread(&helper_fadeout, 0, (void*) fade); + #endif + break; + default: + errno = EINVAL; + err_ret("(%s) ERROR - Unknown direction for fading", prog, index, globalindex); + free(fade); + return AL_FALSE; + break; + } + + #ifndef _WIN32 + pthread_detach(thread); + #endif + + alGetError(); /* clear any AL errors beforehand + + return AL_TRUE; + } + + + ALboolean openal_fadeout (uint32_t index, uint16_t quantity) { + /*wrapper for fadeout + return openal_fade(index, quantity, FADE_OUT); + } + + + ALboolean openal_fadein (uint32_t index, uint16_t quantity) { + /*wrapper for fadein + return openal_fade(index, quantity, FADE_IN); + } + + + ALboolean openal_setposition (uint32_t index, float x, float y, float z) { + if (oalbReady == AL_FALSE) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return AL_FALSE; + } + + if (index >= globalsize) { + errno = EINVAL; + err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); + return AL_FALSE; + } + + alSource3f(Sources[index], AL_POSITION, x, y, z); + if (AlGetError2("(%s) ERROR - Failed to set position for sound %d)", index) != AL_TRUE) + return AL_FALSE; + + return AL_TRUE; + } + + */ + +void oalb_playsound (const uint32_t iIndex, const char bLoop) { + if (oalbReady == AL_FALSE) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return; } - - ALboolean openal_setglobalvolume (uint8_t percentage) { - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - /*Set volume for all sounds*/ - if (percentage > 100) - percentage = 100; - alListenerf (AL_GAIN, (float) percentage/100.0f); - if (AlGetError("(%s) ERROR - Failed to set global volume") != AL_TRUE) - return AL_FALSE; - - alGetError(); /* clear any AL errors beforehand */ - - return AL_TRUE; + /*Play sound number index*/ + if(iIndex < 0 || iIndex >= iNumSounds) { + errno = EINVAL; + err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex); + return; } - - - ALboolean openal_togglemute () { - /*Mute or unmute sound*/ - ALfloat mute; - - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - alGetListenerf (AL_GAIN, &mute); - if (mute > 0) - mute = 0; - else - mute = 1.0; - alListenerf (AL_GAIN, mute); - if (AlGetError("(%s) ERROR - Failed to set mute property") != AL_TRUE) - return AL_FALSE; - - alGetError(); /* clear any AL errors beforehand */ - - return AL_TRUE; - } + SSound_play(&aSounds[iIndex], bLoop); - ALboolean openal_fade (uint32_t index, uint16_t quantity, ALboolean direction) { - /*Fade in or out by calling a helper thread*/ -#ifndef _WIN32 - pthread_t thread; -#else - HANDLE Thread; - DWORD threadID; -#endif - fade_t *fade; - - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - fade = (fade_t*) Malloc(sizeof(fade_t)); - fade->index = index; - fade->quantity = quantity; - - if (index >= globalsize) { - errno = EINVAL; - err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); - return AL_FALSE; - } - - switch (direction) { - case FADE_IN: -#ifndef _WIN32 - pthread_create(&thread, NULL, helper_fadein, (void*) fade); -#else - Thread = _beginthread(&helper_fadein, 0, (void*) fade); -#endif - break; - case FADE_OUT: -#ifndef _WIN32 - pthread_create(&thread, NULL, helper_fadeout, (void*) fade); -#else - Thread = _beginthread(&helper_fadeout, 0, (void*) fade); -#endif - break; - default: - errno = EINVAL; - err_ret("(%s) ERROR - Unknown direction for fading", prog, index, globalindex); - free(fade); - return AL_FALSE; - break; - } - -#ifndef _WIN32 - pthread_detach(thread); -#endif - - alGetError(); /* clear any AL errors beforehand */ - - return AL_TRUE; + + alGetError(); /* clear any AL errors beforehand */ + + return; +} + + +void oalb_pausesound (const uint32_t iIndex) { + if (oalbReady == AL_FALSE) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return; + } + + /*Pause sound number index*/ + if(iIndex < 0 || iIndex >= iNumSounds) { + errno = EINVAL; + err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex); + return; + } + SSound_pause(&aSounds[iIndex]); + + if (AlGetError2("(%s) ERROR - Failed to pause sound %d)", iIndex) != AL_TRUE) + return; + + return; +} + + +void oalb_stopsound (const uint32_t iIndex) { + if (oalbReady == AL_FALSE) { + errno = EPERM; + err_ret("(%s) WARN - OpenAL not initialized", prog); + return; } + /*Stop sound number index*/ + if(iIndex < 0 || iIndex >= iNumSounds) { + errno = EINVAL; + err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex); + return; + } + SSound_stop(&aSounds[iIndex]); - ALboolean openal_fadeout (uint32_t index, uint16_t quantity) { - /*wrapper for fadeout*/ - return openal_fade(index, quantity, FADE_OUT); + if (AlGetError2("(%s) ERROR - Failed to stop sound %d)", iIndex) != AL_TRUE) + return; + + alGetError(); /* clear any AL errors beforehand */ + + return; +} + + +/*SSOUND STUFF HERE*/ + +char SSound_load (SSound_t* pSound, const char* cFilename) { + uint32_t magic; + ALenum format; + ALsizei bitsize, freq; + char *data; + FILE* fp; + + snprintf(pSound->Filename, 256, "%s", cFilename); + pSound->source = -1; + alGenBuffers(1, &pSound->Buffer); + + if(alGetError() != AL_NO_ERROR) { + fprintf(stderr, "CSound: Couldn't create buffer.\n"); + return 0; } + fp = fopen(pSound->Filename, "rb"); - ALboolean openal_fadein (uint32_t index, uint16_t quantity) { - /*wrapper for fadein*/ - return openal_fade(index, quantity, FADE_IN); + if(!fp) { + fprintf(stderr, "CSound: Couldn't open file for reading.\n"); + return 0; + } + + if(fread(&magic, sizeof(uint32_t), 1, fp) < 1) + { + fclose(fp); + fprintf(stderr, "CSound: Couldn't read file header.\n"); + return 0; + } + fclose(fp); + + switch (ENDIAN_BIG_32(magic)) { + case OGG_FILE_FORMAT: + load_oggvorbis (pSound->Filename, &format, &data, &bitsize, &freq); + break; + case WAV_FILE_FORMAT: + load_wavpcm (pSound->Filename, &format, &data, &bitsize, &freq); + break; + default: + errno = EINVAL; + err_ret ("(%s) ERROR - File format (%08X) not supported", prog, ENDIAN_BIG_32(magic)); + return 0; + break; } - - ALboolean openal_setposition (uint32_t index, float x, float y, float z) { - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - if (index >= globalsize) { - errno = EINVAL; - err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); - return AL_FALSE; - } - - alSource3f(Sources[index], AL_POSITION, x, y, z); - if (AlGetError2("(%s) ERROR - Failed to set position for sound %d)", index) != AL_TRUE) - return AL_FALSE; - - return AL_TRUE; + alBufferData(pSound->Buffer, format, data, bitsize, freq); + if(alGetError() != AL_NO_ERROR) + { + fprintf(stderr, "CSound: Couldn't write buffer data.\n"); + return 0; } - + free(data); - ALboolean openal_playsound (uint32_t index){ - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - /*Play sound number index*/ - if (index >= globalsize) { - errno = EINVAL; - err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); - return AL_FALSE; - } - alSourcePlay(Sources[index]); - if (AlGetError2("(%s) ERROR - Failed to play sound %d)", index) != AL_TRUE) - return AL_FALSE; - - alGetError(); /* clear any AL errors beforehand */ - - return AL_TRUE; - } - + return 1; +} + +void SSound_close(SSound_t* pSound) +{ + SSound_stop(pSound); + alDeleteBuffers(1, &pSound->Buffer); +} + +void SSound_play(SSound_t* pSound, const char bLoop) { + int i; - ALboolean openal_pausesound(uint32_t index){ - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; + if(pSound->source == -1) // need a new source + { + int i; + for(i = 0; i < MAX_SOURCES; i++) + { + ALint state; + alGetSourcei(sources[i], AL_SOURCE_STATE, &state); + if(state != AL_PLAYING && state != AL_PAUSED) + { +#ifdef DEBUG + printf("using source %d (state 0x%x) for buffer.\n", i, state); +#endif + alSourceStop(sources[pSound->source]); + alGetError(); + break; + } } - - /*Pause sound number index*/ - if (index >= globalsize) { - errno = EINVAL; - err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); - return AL_FALSE; + if(i == MAX_SOURCES) // no available source found; skip + { +#ifdef DEBUG + printf("no source to play buffer %d!\n", i); +#endif + return; } - alSourcePause(Sources[index]); - if (AlGetError2("(%s) ERROR - Failed to pause sound %d)", index) != AL_TRUE) - return AL_FALSE; - - return AL_TRUE; + pSound->source = i; + } + else // reuse already playing source + { + alSourceStop(sources[pSound->source]); } - + alSourcei (sources[pSound->source], AL_BUFFER, pSound->Buffer); + alSourcef (sources[pSound->source], AL_PITCH, 1.0f); + alSourcef (sources[pSound->source], AL_GAIN, 1.0f); + alSourcefv(sources[pSound->source], AL_POSITION, NV ); + alSourcefv(sources[pSound->source], AL_VELOCITY, NV ); + alSourcei (sources[pSound->source], AL_LOOPING, bLoop ); + alSourcePlay(sources[pSound->source]); - ALboolean openal_stopsound(uint32_t index){ - if (openalReady == AL_FALSE) { - errno = EPERM; - err_ret("(%s) WARN - OpenAL not initialized", prog); - return AL_FALSE; - } - - /*Stop sound number index*/ - if (index >= globalsize) { - errno = EINVAL; - err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex); - return AL_FALSE; - } - alSourceStop(Sources[index]); - if (AlGetError2("(%s) ERROR - Failed to stop sound %d)", index) != AL_TRUE) - return AL_FALSE; - - alGetError(); /* clear any AL errors beforehand */ - - return AL_TRUE; + if((i = alGetError()) != AL_NO_ERROR) + { + fprintf(stderr, "CSound: SourcePlay error 0x%4x in source %d\n", i, pSound->source); } - -#ifdef __CPLUSPLUS +#ifdef DEBUG + fprintf(stderr, "play %s%s [%d]\n", pSound->Filename, bLoop ? " forever" : " once", pSound->source); +#endif +} + +void SSound_pause(const SSound_t* pSound) { + if(pSound->source == -1) // not playing + return; + alSourcePause(sources[pSound->source]); +#ifdef DEBUG + fprintf(stderr, "pause %s\n", pSound->Filename); +#endif } + +void SSound_continue(const SSound_t* pSound) { + if(pSound->source == -1) // not playing + return; + alSourcePlay(sources[pSound->source]); +#ifdef DEBUG + fprintf(stderr, "pause %s\n", pSound->Filename); #endif +} + +void SSound_stop(SSound_t* pSound) { + if(pSound->source == -1) // not playing + return; + alSourceStop(sources[pSound->source]); + pSound->source = -1; +#ifdef DEBUG + fprintf(stderr, "stop %s\n", pSound->Filename); +#endif +} + +void SSound_volume(const SSound_t* pSound, const float fPercentage) { + if(pSound->source == -1) // not playing + return; + alSourcef(sources[pSound->source], AL_GAIN, fPercentage); +} +