openalbridge/openalbridge.c
author nemo
Thu, 15 Oct 2009 19:24:14 +0000
changeset 2464 851b4e47ed2b
parent 2446 cbb3af76bcc0
child 2494 1e10a47cabea
permissions -rw-r--r--
oops. shotgun reload

/*
 * OpenAL Bridge - a simple portable library for OpenAL interface
 * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>,
 *                    Mario Liebisch <mario.liebisch+hw@googlemail.com>
 *
 * 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
 * the Free Software Foundation; version 2 of the License
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include "openalbridge.h"


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
 */

const char oalb_init (const char* programname, const char usehardware) {                
        prog = (char *) programname;
        
        if (oalbReady == AL_TRUE) {
                errno = EPERM;                
                err_ret("(%s) WARN - OpenAL already initialized", prog);
                return AL_FALSE;
        }
        
#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;
        }
        
        err_msg("(%s) INFO - Using OpenAL device: %s", prog, alcGetString(device, ALC_DEVICE_SPECIFIER));
        
        context = alcCreateContext(device, NULL);
        alcMakeContextCurrent(context);
        
        if (AlGetError("(%s) WARN - Failed to create a new contex") != AL_TRUE)
                return AL_FALSE;
        
        /*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
 * Stop all sounds, deallocate all memory and close OpenAL
 *  RETURN
 * -
 */

void oalb_close (void) {
        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)  
 *
 *  ARGUMENTS
 * -
 *  DESCRIPTION
 *
 *  RETURN
 * -
 */

char oalb_ready (void) {
        return oalbReady;
}

/**
 * const int32_t oalb_loadfile (const char *filename) 
 *
 *  ARGUMENTS
 * -
 *  DESCRIPTION
 *
 *  RETURN
 * -
 */

const 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;
        }
        
        
        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;
        
}


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 (%d) out of bounds", prog, iIndex);
                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);
        
        if (AlGetError("(%s) ERROR -  Failed to set global volume") != AL_TRUE)
                return;
        
        alGetError();  /* clear any AL errors beforehand */
        
        return;
}

    
void oalb_togglemute (void) {
        /*Mute or unmute sound*/
        ALfloat mute;
        
        if (oalbReady == AL_FALSE) {
                errno = EPERM;                
                err_ret("(%s) WARN - OpenAL not initialized", prog);
                return;
        }
        
        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;
        
        alGetError();  /* clear any AL errors beforehand */
        
        return;
}
 /*
 
 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;
        }
        
        /*Play sound number index*/
        if(iIndex < 0 || iIndex >= iNumSounds) {
                errno = EINVAL;
                err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
                return;
        }
        SSound_play(&aSounds[iIndex], bLoop);
        
        
        
        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]);
        
        if (AlGetError2("(%s) ERROR - Failed to stop sound %d)", iIndex) != AL_TRUE)
                return;
        
        alGetError();  /* clear any AL errors beforehand */
        
        return;
}