openalbridge/openalbridge.c
changeset 2494 1e10a47cabea
parent 2446 cbb3af76bcc0
child 2496 8ea93b0d49ee
equal deleted inserted replaced
2493:08313e4080e4 2494:1e10a47cabea
     1 /*
     1 /*
     2  * OpenAL Bridge - a simple portable library for OpenAL interface
     2  * OpenAL Bridge - a simple portable library for OpenAL interface
     3  * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>,
     3  * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara@gmail.com>
     4  *                    Mario Liebisch <mario.liebisch+hw@googlemail.com>
       
     5  *
     4  *
     6  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     7  * it under the terms of the GNU Lesser General Public License as published by
     6  * it under the terms of the GNU Lesser General Public License as published by
     8  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     9  *
     8  *
    17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    18  */
    17  */
    19 
    18 
    20 #include "openalbridge.h"
    19 #include "openalbridge.h"
    21 
    20 
    22 
    21 char oalbReady = 0;
       
    22 int iNumSounds = 0;
    23 char *prog;
    23 char *prog;
    24 
    24 /*Sources are points emitting sound*/
    25 /*Buffers hold sound data*/
    25 ALuint Sources[MAX_SOURCES];
    26 ALuint *Buffers;
    26 
    27 /*index for Sources and Buffers*/
    27 /*structure that holds information about sounds*/
    28 ALuint globalindex, globalsize, increment;
    28 SSound_t *theSounds;
    29 
    29 
    30 //null vector
    30 ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; /*Position of the source sound*/
    31 const ALfloat NV[] = {0.0f, 0.0f, 0.0f};
    31 ALfloat SourceVel[] = { 0.0, 0.0, 0.0 }; /*Velocity of the source sound*/
    32 //listener orientation
       
    33 const ALfloat LO[] = {0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f};
       
    34 
       
    35 SSound_t aSounds[MAX_SOUNDS];
       
    36 int iNumSounds = 0;
       
    37 char oalbReady = 0;
       
    38 
       
    39 ALCcontext *context;
       
    40 ALCdevice *device;
       
    41 ALuint sources[MAX_SOURCES];
       
    42 
       
    43 
       
    44 
       
    45 
    32 
    46 /**
    33 /**
    47  * const char oalb_init (const char* programname, const char usehardware) 
    34  * const char oalb_init (const char* programname, const char usehardware) 
    48  *
    35  *
    49  *  ARGUMENTS
    36  *  ARGUMENTS
    54  *  RETURN
    41  *  RETURN
    55  * 1 success
    42  * 1 success
    56  * 2 error
    43  * 2 error
    57  */
    44  */
    58 
    45 
    59 const char oalb_init (const char* programname, const char usehardware) {                
    46 const char oalb_init (const char* programname, const char usehardware) {	
       
    47         /*Initialize an OpenAL contex and allocate memory space for data and buffers*/
       
    48         ALCcontext *context;
       
    49         ALCdevice *device;
       
    50         const ALCchar *default_device;
       
    51         int i;
       
    52         
    60         prog = (char *) programname;
    53         prog = (char *) programname;
    61         
    54         
    62         if (oalbReady == AL_TRUE) {
    55         /*Position of the listener*/
       
    56         ALfloat ListenerPos[] = {0.0, 0.0, 0.0};
       
    57         /*Velocity of the listener*/
       
    58         ALfloat ListenerVel[] = {0.0, 0.0, 0.0};
       
    59         /*Orientation of the listener. (first 3 elements are "at", second 3 are "up")*/
       
    60         ALfloat ListenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0};
       
    61         
       
    62         if (oalbReady == 1) {
    63                 errno = EPERM;                
    63                 errno = EPERM;                
    64                 err_ret("(%s) WARN - OpenAL already initialized", prog);
    64                 err_ret("(%s) WARN - OpenAL already initialized", prog);
    65                 return AL_FALSE;
    65                 return AL_FALSE;
    66         }
    66         }
    67         
    67         
    86         if (device == NULL) {
    86         if (device == NULL) {
    87                 errno = ENODEV;                
    87                 errno = ENODEV;                
    88                 err_ret("(%s) WARN - Failed to open sound device", prog);
    88                 err_ret("(%s) WARN - Failed to open sound device", prog);
    89                 return AL_FALSE;
    89                 return AL_FALSE;
    90         }
    90         }
    91         
    91         err_msg("(%s) INFO - Output device: %s", prog, alcGetString(device, ALC_DEVICE_SPECIFIER));
    92         err_msg("(%s) INFO - Using OpenAL device: %s", prog, alcGetString(device, ALC_DEVICE_SPECIFIER));
       
    93         
    92         
    94         context = alcCreateContext(device, NULL);
    93         context = alcCreateContext(device, NULL);
    95         alcMakeContextCurrent(context);
    94         alcMakeContextCurrent(context);
    96         
    95         alcProcessContext(context);
    97         if (AlGetError("(%s) WARN - Failed to create a new contex") != AL_TRUE)
    96         
       
    97         if (AlGetError("(%s) ERROR - Failed to create a new contex") != AL_TRUE)
    98                 return AL_FALSE;
    98                 return AL_FALSE;
    99         
    99         
   100         /*set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation*/
   100         /*set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation*/
   101         alListenerf (AL_GAIN,        1.0f);
   101         alListenerf (AL_GAIN,        1.0f       );
   102         alListenerfv(AL_POSITION,    NV);
   102         alListenerfv(AL_POSITION,    ListenerPos);
   103         alListenerfv(AL_VELOCITY,    NV);
   103         alListenerfv(AL_VELOCITY,    ListenerVel);
   104         alListenerfv(AL_ORIENTATION, LO);
   104         alListenerfv(AL_ORIENTATION, ListenerOri);
   105         
       
   106         alcProcessContext(context);
       
   107         
   105         
   108         if (AlGetError("(%s) WARN - Failed to set Listener properties") != AL_TRUE)
   106         if (AlGetError("(%s) WARN - Failed to set Listener properties") != AL_TRUE)
   109                 return AL_FALSE;
   107                 return AL_FALSE;
   110         
   108         
   111         alGenSources(MAX_SOURCES, sources);
   109         theSounds = (SSound_t*) Malloc(sizeof(SSound_t)*MAX_SOUNDS);
   112         
   110         for (i = 0; i < MAX_SOUNDS; i++) {
   113         oalbReady = AL_TRUE;
   111                 theSounds->isLoaded = 0;
       
   112                 theSounds->sourceIndex = -1;
       
   113         }
       
   114         
       
   115         alGenSources(MAX_SOURCES, Sources);
       
   116         oalbReady = 1;
   114         
   117         
   115         alGetError();  /* clear any AL errors beforehand */
   118         alGetError();  /* clear any AL errors beforehand */
   116         return AL_TRUE;
   119         return AL_TRUE;
   117 }
   120 }
   118 
   121 
   127  *  RETURN
   130  *  RETURN
   128  * -
   131  * -
   129  */
   132  */
   130 
   133 
   131 void oalb_close (void) {
   134 void oalb_close (void) {
       
   135         /*Stop all sounds, deallocate all memory and close OpenAL */
       
   136         ALCcontext *context;
       
   137         ALCdevice  *device;
   132         int i;
   138         int i;
   133         
   139         
   134         if (oalbReady == 0) {
   140         if (oalbReady == 0) {
   135                 errno = EPERM;
   141                 errno = EPERM;
   136                 err_ret("(%s) WARN - OpenAL not initialized", prog);
   142                 err_ret("(%s) WARN - OpenAL not initialized", prog);
   137                 return;
   143                 return;
   138         }
   144         }
   139         
   145         
   140         for(i = 0; i < iNumSounds; i++) {
   146         alSourceStopv	(MAX_SOURCES, Sources);
   141                 SSound_stop(&aSounds[i]);
   147         alDeleteSources (MAX_SOURCES, Sources);
   142                 SSound_close(&aSounds[i]);
   148         
   143         }
   149         for (i = 0; i < MAX_SOUNDS; i++) {
   144         
   150                 free(theSounds[i].filename);
   145         alSourceStopv (MAX_SOURCES, sources);
   151                 alDeleteBuffers (1, &theSounds[i].Buffer);
   146         alDeleteSources (MAX_SOURCES, sources);
   152         }
       
   153         free(theSounds);
       
   154         
       
   155         context = alcGetCurrentContext();
       
   156         device  = alcGetContextsDevice(context);
   147         
   157         
   148         alcMakeContextCurrent(NULL);
   158         alcMakeContextCurrent(NULL);
   149         alcDestroyContext(context);
   159         alcDestroyContext(context);
   150         alcCloseDevice(device);
   160         alcCloseDevice(device);
   151         
   161         
   166  */
   176  */
   167 
   177 
   168 char oalb_ready (void) {
   178 char oalb_ready (void) {
   169         return oalbReady;
   179         return oalbReady;
   170 }
   180 }
       
   181 /*
       
   182  ALboolean helper_realloc (void) {
       
   183  expands allocated memory when loading more sound files than expected
       
   184  int oldsize = globalsize;
       
   185  globalsize += increment;
       
   186  
       
   187  #ifdef DEBUG
       
   188  err_msg("(%s) INFO - Realloc in process from %d to %d\n", prog, oldsize, globalsize);
       
   189  #endif
       
   190  
       
   191  Buffers = (ALuint*) Realloc(Buffers, sizeof(ALuint)*globalsize);
       
   192  Sources = (ALuint*) Realloc(Sources, sizeof(ALuint)*globalsize);
       
   193  
       
   194  return AL_TRUE;
       
   195  }*/
   171 
   196 
   172 /**
   197 /**
   173  * const int32_t oalb_loadfile (const char *filename) 
   198  * const int32_t oalb_loadfile (const char *filename) 
   174  *
   199  *
   175  *  ARGUMENTS
   200  *  ARGUMENTS
   178  *
   203  *
   179  *  RETURN
   204  *  RETURN
   180  * -
   205  * -
   181  */
   206  */
   182 
   207 
   183 const int32_t oalb_loadfile (const char *filename) {
   208 const int32_t oalb_loadfile (const char *filename){
   184         int i;
   209         /*Open a file, load into memory and allocate the Source buffer for playing*/
       
   210         
       
   211         ALenum format, error;
       
   212         ALsizei bitsize, freq;
       
   213         char *data;
       
   214         int namelength, i;
       
   215         uint32_t magic;
       
   216         FILE *fp;
   185         
   217         
   186         if (oalbReady == 0) {
   218         if (oalbReady == 0) {
   187                 errno = EPERM;                
   219                 errno = EPERM;                
   188                 err_ret("(%s) WARN - OpenAL not initialized", prog);
   220                 err_ret("(%s) WARN - OpenAL not initialized", prog);
   189                 return -1;
   221                 return -1;
   190         }
   222         }
   191         
   223         
   192         if(iNumSounds == MAX_SOUNDS) {
   224         /*when the buffers are all used, we can expand memory to accept new files*/
   193                 err_msg("(%s) WARN - Maximum number of sound samples reached", prog);
   225         //     if (globalindex == globalsize)
       
   226         //            helper_realloc();
       
   227         
       
   228         namelength=strlen(filename);
       
   229         /*if this sound is already loaded return the index from theSounds*/
       
   230         for (i = 0; i < iNumSounds; i++){
       
   231                 if (theSounds[iNumSounds].isLoaded == 1) {
       
   232                         if (strncmp(theSounds[iNumSounds].filename, filename, namelength) == 0)
       
   233                                 return i;
       
   234                 }
       
   235         }
       
   236         
       
   237         /*else load it and store it into a theSounds cell*/
       
   238         
       
   239         /*detect the file format, as written in the first 4 bytes of the header*/
       
   240         fp = Fopen (filename, "rb");
       
   241         
       
   242         if (fp == NULL)
       
   243                 return -1;
       
   244         
       
   245         error = fread (&magic, sizeof(uint32_t), 1, fp);
       
   246         fclose (fp);
       
   247         
       
   248         if (error < 0) {
       
   249                 errno = EIO;
       
   250                 err_ret("(%s) ERROR - File %s is too short", prog, filename);
       
   251                 return -2;
       
   252         }
       
   253         
       
   254         switch (ENDIAN_BIG_32(magic)) {
       
   255                 case OGG_FILE_FORMAT:
       
   256                         error = load_oggvorbis (filename, &format, &data, &bitsize, &freq);
       
   257                         break;
       
   258                 case WAV_FILE_FORMAT:
       
   259                         error = load_wavpcm (filename, &format, &data, &bitsize, &freq);
       
   260                         break;
       
   261                 default:
       
   262                         errno = EINVAL;
       
   263                         err_ret ("(%s) ERROR - File format (%08X) not supported", prog, ENDIAN_BIG_32(magic));
       
   264                         return -5;
       
   265                         break;
       
   266         }
       
   267         
       
   268         theSounds[iNumSounds].filename = (char*) Malloc(sizeof(char) * namelength);
       
   269         strncpy(theSounds[iNumSounds].filename, filename, namelength);
       
   270         theSounds[iNumSounds].isLoaded = 1;
       
   271         
       
   272         /*prepare the buffer to receive data*/
       
   273         alGenBuffers(1, &theSounds[iNumSounds].Buffer);
       
   274         
       
   275         if (AlGetError("(%s) ERROR - Failed to allocate memory for buffers") != AL_TRUE)
   194                 return -3;
   276                 return -3;
   195         }
   277         
   196         
   278         /*copy pcm data in one buffer*/
   197         
   279         alBufferData(theSounds[iNumSounds].Buffer, format, data, bitsize, freq);
   198         for(i = 0; i < iNumSounds; i++)
   280         /*deallocate data to save memory*/
   199                 if(strcmp(aSounds[i].Filename, filename) == 0)
   281         free(data);		
   200                         return i;
   282         
   201         
   283         if (AlGetError("(%s) ERROR - Failed to write data to buffers") != AL_TRUE)
   202         if(SSound_load(&aSounds[iNumSounds], filename))
   284                 return -6;
   203                 return iNumSounds++;
   285         
   204         else
   286         alGetError();  /* clear any AL errors beforehand */
   205                 return -2;
   287         
   206         
   288         /*returns the index of the source you just loaded, increments it and exits*/
   207 }
   289         return iNumSounds++;
       
   290 }
       
   291 
   208 
   292 
   209 
   293 
   210 void oalb_setvolume (const uint32_t iIndex,  const char cPercentage) {
   294 void oalb_setvolume (const uint32_t iIndex,  const char cPercentage) {
       
   295         float percentage;
       
   296         
   211         if (oalbReady == 0) {
   297         if (oalbReady == 0) {
   212                 errno = EPERM;                
   298                 errno = EPERM;                
   213                 err_ret("(%s) WARN - OpenAL not initialized", prog);
   299                 err_ret("(%s) WARN - OpenAL not initialized", prog);
   214                 return;
   300                 return;
   215         }
   301         }
   220                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
   306                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
   221                 return;
   307                 return;
   222         }
   308         }
   223         
   309         
   224         if(cPercentage > 100)
   310         if(cPercentage > 100)
   225                 SSound_volume(&aSounds[iIndex], 1.0f);
   311                 percentage = 1.0f;
   226         else
   312         else
   227                 SSound_volume(&aSounds[iIndex], cPercentage / 100.0f);
   313                 percentage = cPercentage / 100.0f;
       
   314         
       
   315         alSourcef(Sources[theSounds[iIndex].sourceIndex], AL_GAIN, percentage);
   228         
   316         
   229         if (AlGetError2("(%s) ERROR -  Failed to set volume for sound %d\n", iIndex) != AL_TRUE)
   317         if (AlGetError2("(%s) ERROR -  Failed to set volume for sound %d\n", iIndex) != AL_TRUE)
   230                 return;
   318                 return;
   231         
   319         
   232         alGetError();  /* clear any AL errors beforehand */
   320         alGetError();  /* clear any AL errors beforehand */
   233         
   321         
   234         return;
   322         return;
   235 }
   323 }
       
   324 
   236 
   325 
   237 
   326 
   238 void oalb_setglobalvolume (const char cPercentage) {
   327 void oalb_setglobalvolume (const char cPercentage) {
   239         if (oalbReady == 0) {
   328         if (oalbReady == 0) {
   240                 errno = EPERM;                
   329                 errno = EPERM;                
   254         alGetError();  /* clear any AL errors beforehand */
   343         alGetError();  /* clear any AL errors beforehand */
   255         
   344         
   256         return;
   345         return;
   257 }
   346 }
   258 
   347 
   259     
       
   260 void oalb_togglemute (void) {
   348 void oalb_togglemute (void) {
   261         /*Mute or unmute sound*/
   349         /*Mute or unmute sound*/
   262         ALfloat mute;
   350         ALfloat mute;
   263         
   351         
   264         if (oalbReady == AL_FALSE) {
   352         if (oalbReady == AL_FALSE) {
   280         
   368         
   281         alGetError();  /* clear any AL errors beforehand */
   369         alGetError();  /* clear any AL errors beforehand */
   282         
   370         
   283         return;
   371         return;
   284 }
   372 }
   285  /*
   373 
   286  
   374 
   287  ALboolean openal_fade (uint32_t index, uint16_t quantity, ALboolean direction) {
   375 void oalb_fade (uint32_t iIndex, uint16_t quantity, ALboolean direction) {
   288  /*Fade in or out by calling a helper thread
   376         /*Fade in or out by calling a helper thread*/
   289  #ifndef _WIN32
   377 #ifndef _WIN32
   290  pthread_t thread;
   378         pthread_t thread;
   291  #else
   379 #else
   292  HANDLE Thread;
   380         HANDLE Thread;
   293  DWORD threadID;
   381         DWORD threadID;
   294  #endif
   382 #endif
   295  fade_t *fade;
   383         fade_t *fade;
   296  
   384         
   297  if (oalbReady == AL_FALSE) {
   385         if (oalbReady == 0) {
       
   386                 errno = EPERM;                
       
   387                 err_ret("(%s) WARN - OpenAL not initialized", prog);
       
   388                 return ;
       
   389         }
       
   390         
       
   391         fade = (fade_t*) Malloc(sizeof(fade_t));
       
   392         fade->index = iIndex;
       
   393         fade->quantity = quantity;
       
   394         
       
   395         if(iIndex < 0 || iIndex >= iNumSounds) {
       
   396                 errno = EINVAL;
       
   397                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
       
   398                 return;
       
   399         }
       
   400         
       
   401         switch (direction) {
       
   402                 case FADE_IN:
       
   403 #ifndef _WIN32
       
   404                         pthread_create(&thread, NULL, helper_fadein, (void*) fade);
       
   405 #else
       
   406                         Thread = _beginthread(&helper_fadein, 0, (void*) fade);
       
   407 #endif
       
   408                         break;
       
   409                 case FADE_OUT:
       
   410 #ifndef _WIN32
       
   411                         pthread_create(&thread, NULL, helper_fadeout, (void*) fade);
       
   412 #else
       
   413                         Thread = _beginthread(&helper_fadeout, 0, (void*) fade);
       
   414 #endif	
       
   415                         break;
       
   416                 default:
       
   417                         errno = EINVAL;
       
   418                         err_ret("(%s) ERROR - Unknown direction for fading", prog, index);
       
   419                         free(fade);
       
   420                         return;
       
   421                         break;
       
   422         }
       
   423         
       
   424 #ifndef _WIN32
       
   425         pthread_detach(thread);
       
   426 #endif
       
   427         
       
   428         alGetError();  /* clear any AL errors beforehand */
       
   429         
       
   430         return;
       
   431 }
       
   432 
       
   433 
       
   434 void oalb_fadeout (uint32_t index, uint16_t quantity) {
       
   435         /*wrapper for fadeout*/
       
   436         oalb_fade(index, quantity, FADE_OUT);
       
   437         return;
       
   438 }
       
   439 
       
   440 
       
   441 void oalb_fadein (uint32_t index, uint16_t quantity) {
       
   442         /*wrapper for fadein*/
       
   443         oalb_fade(index, quantity, FADE_IN);
       
   444         return;
       
   445 }
       
   446  
       
   447 
       
   448 /*      ALboolean openal_setposition (uint32_t index, float x, float y, float z) {
       
   449  if (openalReady == AL_FALSE) {
   298  errno = EPERM;                
   450  errno = EPERM;                
   299  err_ret("(%s) WARN - OpenAL not initialized", prog);
   451  err_ret("(%s) WARN - OpenAL not initialized", prog);
   300  return AL_FALSE;
   452  return AL_FALSE;
   301  }
   453  }
   302  
       
   303  fade = (fade_t*) Malloc(sizeof(fade_t));
       
   304  fade->index = index;
       
   305  fade->quantity = quantity;
       
   306  
   454  
   307  if (index >= globalsize) {
   455  if (index >= globalsize) {
   308  errno = EINVAL;
   456  errno = EINVAL;
   309  err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex);
   457  err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex);
   310  return AL_FALSE;
   458  return AL_FALSE;
   311  }
   459  }
   312  
   460  
   313  switch (direction) {
       
   314  case FADE_IN:
       
   315  #ifndef _WIN32
       
   316  pthread_create(&thread, NULL, helper_fadein, (void*) fade);
       
   317  #else
       
   318  Thread = _beginthread(&helper_fadein, 0, (void*) fade);
       
   319  #endif
       
   320  break;
       
   321  case FADE_OUT:
       
   322  #ifndef _WIN32
       
   323  pthread_create(&thread, NULL, helper_fadeout, (void*) fade);
       
   324  #else
       
   325  Thread = _beginthread(&helper_fadeout, 0, (void*) fade);
       
   326  #endif	
       
   327  break;
       
   328  default:
       
   329  errno = EINVAL;
       
   330  err_ret("(%s) ERROR - Unknown direction for fading", prog, index, globalindex);
       
   331  free(fade);
       
   332  return AL_FALSE;
       
   333  break;
       
   334  }
       
   335  
       
   336  #ifndef _WIN32
       
   337  pthread_detach(thread);
       
   338  #endif
       
   339  
       
   340  alGetError();  /* clear any AL errors beforehand 
       
   341  
       
   342  return AL_TRUE;
       
   343  }
       
   344  
       
   345  
       
   346  ALboolean openal_fadeout (uint32_t index, uint16_t quantity) {
       
   347  /*wrapper for fadeout
       
   348  return openal_fade(index, quantity, FADE_OUT);
       
   349  }
       
   350  
       
   351  
       
   352  ALboolean openal_fadein (uint32_t index, uint16_t quantity) {
       
   353  /*wrapper for fadein
       
   354  return openal_fade(index, quantity, FADE_IN);
       
   355  }
       
   356  
       
   357  
       
   358  ALboolean openal_setposition (uint32_t index, float x, float y, float z) {
       
   359  if (oalbReady == AL_FALSE) {
       
   360  errno = EPERM;                
       
   361  err_ret("(%s) WARN - OpenAL not initialized", prog);
       
   362  return AL_FALSE;
       
   363  }
       
   364  
       
   365  if (index >= globalsize) {
       
   366  errno = EINVAL;
       
   367  err_ret("(%s) ERROR - Index out of bounds (got %d, max %d)", prog, index, globalindex);
       
   368  return AL_FALSE;
       
   369  }
       
   370  
       
   371  alSource3f(Sources[index], AL_POSITION, x, y, z);
   461  alSource3f(Sources[index], AL_POSITION, x, y, z);
   372  if (AlGetError2("(%s) ERROR - Failed to set position for sound %d)", index) != AL_TRUE)
   462  if (AlGetError2("(%s) ERROR - Failed to set position for sound %d)", index) != AL_TRUE)
   373  return AL_FALSE;
   463  return AL_FALSE;
   374  
   464  
   375  return AL_TRUE;
   465  return AL_TRUE;
   376  }
   466  }*/
   377  
   467 
   378  */
   468 
   379 
   469 void oalb_playsound (const uint32_t iIndex, const char bLoop){
   380 void oalb_playsound (const uint32_t iIndex, const char bLoop) {
   470         int findNewSource;
   381         if (oalbReady == AL_FALSE) {
   471         int i, j, state;
       
   472         
       
   473         if (oalbReady == 0) {
   382                 errno = EPERM;                
   474                 errno = EPERM;                
   383                 err_ret("(%s) WARN - OpenAL not initialized", prog);
   475                 err_ret("(%s) WARN - OpenAL not initialized", prog);
   384                 return;
   476                 return;
   385         }
   477         }
   386         
   478         
   388         if(iIndex < 0 || iIndex >= iNumSounds) {
   480         if(iIndex < 0 || iIndex >= iNumSounds) {
   389                 errno = EINVAL;
   481                 errno = EINVAL;
   390                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
   482                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
   391                 return;
   483                 return;
   392         }
   484         }
   393         SSound_play(&aSounds[iIndex], bLoop);
   485         
   394         
   486         /*check if sound has already a source*/
   395         
   487         if (theSounds[iIndex].sourceIndex == -1) {
       
   488                 /*needs a new source*/
       
   489                 findNewSource = 1;
       
   490         } else {
       
   491                 /*already has a source -- check it's not playing*/
       
   492                 alGetSourcei(Sources[theSounds[iIndex].sourceIndex], AL_SOURCE_STATE, &state);
       
   493                 if(state == AL_PLAYING || state == AL_PAUSED) {
       
   494                         /*it is being played, so we have to allocate a new source*/
       
   495                         findNewSource = 1;
       
   496                 } else {
       
   497                         /*it is not being played, so we can use it safely*/
       
   498                         findNewSource = 0;
       
   499                 }
       
   500         }
       
   501         
       
   502         if (findNewSource == 1) {
       
   503 #ifdef DEBUG
       
   504              err_msg("(%s) DEBUG - Looking for a source for sound %d", prog, iIndex);   
       
   505 #endif
       
   506                 for (i = 0; i < MAX_SOURCES; i++) {
       
   507                         alGetSourcei(Sources[i], AL_SOURCE_STATE, &state);
       
   508                         if(state != AL_PLAYING && state != AL_PAUSED) {
       
   509                               //  alSourceStop(Sources[i]);
       
   510                               //  alGetError();
       
   511                                 for(j = 0; j < iNumSounds; j++)
       
   512                                         if(theSounds[j].isLoaded && theSounds[j].sourceIndex == i)
       
   513                                                 theSounds[j].sourceIndex = -1;
       
   514                                 break;
       
   515                         } else {
       
   516                                 //TODO: what happens when all 16 sources are busy?
       
   517                         }
       
   518                 }
       
   519                 theSounds[iIndex].sourceIndex = i;
       
   520         }
       
   521         
       
   522         alSourcei (Sources[theSounds[iIndex].sourceIndex], AL_BUFFER,   theSounds[iIndex].Buffer);
       
   523         alSourcef (Sources[theSounds[iIndex].sourceIndex], AL_PITCH,    1.0f        );
       
   524         alSourcef (Sources[theSounds[iIndex].sourceIndex], AL_GAIN,     1.0f        );
       
   525         alSourcefv(Sources[theSounds[iIndex].sourceIndex], AL_POSITION, SourcePos   );
       
   526         alSourcefv(Sources[theSounds[iIndex].sourceIndex], AL_VELOCITY, SourceVel   );
       
   527         alSourcei (Sources[theSounds[iIndex].sourceIndex], AL_LOOPING,  bLoop       );
       
   528         if (AlGetError("(%s) ERROR - Failed to set Source properties") != AL_TRUE)
       
   529                 return;
       
   530         
       
   531         alSourcePlay(Sources[theSounds[iIndex].sourceIndex]);
       
   532         if (AlGetError2("(%s) ERROR - Failed to play sound %d)", iIndex) != AL_TRUE)
       
   533                 return;
   396         
   534         
   397         alGetError();  /* clear any AL errors beforehand */
   535         alGetError();  /* clear any AL errors beforehand */
   398         
   536         
   399         return;
   537         return;
   400 }
   538 }
   411         if(iIndex < 0 || iIndex >= iNumSounds) {
   549         if(iIndex < 0 || iIndex >= iNumSounds) {
   412                 errno = EINVAL;
   550                 errno = EINVAL;
   413                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
   551                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
   414                 return;
   552                 return;
   415         }
   553         }
   416         SSound_pause(&aSounds[iIndex]);
   554         alSourcePause(Sources[theSounds[iIndex].sourceIndex]);                             
   417         
       
   418         if (AlGetError2("(%s) ERROR - Failed to pause sound %d)", iIndex) != AL_TRUE)
   555         if (AlGetError2("(%s) ERROR - Failed to pause sound %d)", iIndex) != AL_TRUE)
   419                 return;
   556                 return;
   420         
   557         
   421         return;
   558         return;
   422 }
   559 }
   433         if(iIndex < 0 || iIndex >= iNumSounds) {
   570         if(iIndex < 0 || iIndex >= iNumSounds) {
   434                 errno = EINVAL;
   571                 errno = EINVAL;
   435                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
   572                 err_ret("(%s) ERROR - Index (%d) out of bounds", prog, iIndex);
   436                 return;
   573                 return;
   437         }
   574         }
   438         SSound_stop(&aSounds[iIndex]);
   575         alSourceStop(Sources[theSounds[iIndex].sourceIndex]);                             
   439         
   576         
   440         if (AlGetError2("(%s) ERROR - Failed to stop sound %d)", iIndex) != AL_TRUE)
   577         if (AlGetError2("(%s) ERROR - Failed to stop sound %d)", iIndex) != AL_TRUE)
   441                 return;
   578                 return;
   442         
   579         
   443         alGetError();  /* clear any AL errors beforehand */
   580         alGetError();  /* clear any AL errors beforehand */