misc/libopenalbridge/openalbridge.c
changeset 3697 d5b30d6373fc
parent 3529 0e968ba12a84
equal deleted inserted replaced
3695:c11abf387a7d 3697:d5b30d6373fc
    36 // It can be called twice to increase the cache size
    36 // It can be called twice to increase the cache size
    37 int openal_init (void) {
    37 int openal_init (void) {
    38     ALCcontext *context;
    38     ALCcontext *context;
    39     ALCdevice *device;
    39     ALCdevice *device;
    40     int i;
    40     int i;
    41         
    41 
    42     // reuse old context and resize the existing 
    42     // reuse old context and resize the existing
    43     if (openal_ready() == AL_TRUE) {
    43     if (openal_ready() == AL_TRUE) {
    44         fprintf(stderr,"(Bridge Info) - already initialized\n");
    44         fprintf(stderr,"(Bridge Info) - already initialized\n");
    45         instances_number++;
    45         instances_number++;
    46         return AL_TRUE;
    46         return AL_TRUE;
    47     }
    47     }
    48     
    48 
    49     cache_pointer = 0;
    49     cache_pointer = 0;
    50     instances_number++;
    50     instances_number++;
    51     
    51 
    52     // initial memory size
    52     // initial memory size
    53     cache_size = 50;
    53     cache_size = 50;
    54     
    54 
    55     // open hardware device if present
    55     // open hardware device if present
    56     device = alcOpenDevice(NULL);
    56     device = alcOpenDevice(NULL);
    57     sources_number = 16;
    57     sources_number = 16;
    58     if (device == NULL) {
    58     if (device == NULL) {
    59         fprintf(stderr,"(Bridge Warning) - failed to open sound device, using software renderer\n");
    59         fprintf(stderr,"(Bridge Warning) - failed to open sound device, using software renderer\n");
    79         return -2;
    79         return -2;
    80     }
    80     }
    81 
    81 
    82     Sources = (ALuint *)Malloc (sizeof(ALuint) * sources_number);
    82     Sources = (ALuint *)Malloc (sizeof(ALuint) * sources_number);
    83     alGenSources(sources_number, Sources);
    83     alGenSources(sources_number, Sources);
    84     
    84 
    85     // set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation
    85     // set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation
    86     // Position, Velocity and Orientation of the listener
    86     // Position, Velocity and Orientation of the listener
    87     ALfloat ListenerPos[] = {0.0, 0.0, 0.0};
    87     ALfloat ListenerPos[] = {0.0, 0.0, 0.0};
    88     ALfloat ListenerVel[] = {0.0, 0.0, 0.0};
    88     ALfloat ListenerVel[] = {0.0, 0.0, 0.0};
    89     ALfloat ListenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0};
    89     ALfloat ListenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0};
   110 // Stop all sounds, deallocate all memory and close OpenAL context
   110 // Stop all sounds, deallocate all memory and close OpenAL context
   111 void openal_close (void) {
   111 void openal_close (void) {
   112     ALCcontext *context;
   112     ALCcontext *context;
   113     ALCdevice  *device;
   113     ALCdevice  *device;
   114     int i;
   114     int i;
   115     
   115 
   116     if (instances_number == 0) {
   116     if (instances_number == 0) {
   117         fprintf(stderr,"(Bridge Warning) - OpenAL not initialized\n");
   117         fprintf(stderr,"(Bridge Warning) - OpenAL not initialized\n");
   118         return;
   118         return;
   119     }
   119     }
   120 
   120 
   121     instances_number--;
   121     instances_number--;
   122     if (instances_number > 0) {
   122     if (instances_number > 0) {
   123         // release memory only when last session ends
   123         // release memory only when last session ends
   124         return;
   124         return;
   125     }
   125     }
   126     
   126 
   127     for (i = 0; i < cache_size; i++) {
   127     for (i = 0; i < cache_size; i++) {
   128         openal_unloadfile(i);
   128         openal_unloadfile(i);
   129     }
   129     }
   130     free(the_sounds);
   130     free(the_sounds);
   131 
   131 
   146     return;
   146     return;
   147 }
   147 }
   148 
   148 
   149 
   149 
   150 ALboolean openal_ready (void) {
   150 ALboolean openal_ready (void) {
   151     if (instances_number >= 1) 
   151     if (instances_number >= 1)
   152         return AL_TRUE;
   152         return AL_TRUE;
   153     else
   153     else
   154         return AL_FALSE;
   154         return AL_FALSE;
   155 }
   155 }
   156 
   156 
   162     uint32_t fileformat;
   162     uint32_t fileformat;
   163     al_sound_t sound_data;
   163     al_sound_t sound_data;
   164     int len, i, index = -1;
   164     int len, i, index = -1;
   165     char *data;
   165     char *data;
   166     FILE *fp;
   166     FILE *fp;
   167     
   167 
   168     if (openal_ready() == AL_FALSE) {
   168     if (openal_ready() == AL_FALSE) {
   169         fprintf(stderr,"(Bridge Warning) - not initialized\n");
   169         fprintf(stderr,"(Bridge Warning) - not initialized\n");
   170         return -1;
   170         return -1;
   171     }
   171     }
   172     
   172 
   173     // if this sound is already loaded return the index from the_sounds
   173     // if this sound is already loaded return the index from the_sounds
   174     len = strlen(filename);
   174     len = strlen(filename);
   175     for (i = 0; i < cache_size; i++) {
   175     for (i = 0; i < cache_size; i++) {
   176         if (the_sounds[i].filename != NULL && strncmp(the_sounds[i].filename, filename, len) == 0) {
   176         if (the_sounds[i].filename != NULL && strncmp(the_sounds[i].filename, filename, len) == 0) {
   177 #ifdef DEBUG
   177 #ifdef DEBUG
   180             return i;
   180             return i;
   181         }
   181         }
   182         // if we don't have memory available search for a free element
   182         // if we don't have memory available search for a free element
   183         if (cache_pointer >= cache_size)
   183         if (cache_pointer >= cache_size)
   184             if (the_sounds[i].is_used == AL_FALSE)
   184             if (the_sounds[i].is_used == AL_FALSE)
   185                 index = i; 
   185                 index = i;
   186     }
   186     }
   187 
   187 
   188     if (index == -1 && cache_pointer >= cache_size) {
   188     if (index == -1 && cache_pointer >= cache_size) {
   189         fprintf(stderr,"(Bridge Info) - No free spots found; doubling cache size\n", filename);
   189         fprintf(stderr,"(Bridge Info) - No free spots found; doubling cache size\n", filename);
   190         cache_size *= 2;
   190         cache_size *= 2;
   191         the_sounds = (al_sound_t *)Realloc (the_sounds, sizeof(al_sound_t) * cache_size);
   191         the_sounds = (al_sound_t *)Realloc (the_sounds, sizeof(al_sound_t) * cache_size);
   192         for (i = cache_size - 50; i < cache_size; i++) 
   192         for (i = cache_size - 50; i < cache_size; i++)
   193             the_sounds[i] = new_sound_el();
   193             the_sounds[i] = new_sound_el();
   194     } else 
   194     } else
   195         index = ++cache_pointer;
   195         index = ++cache_pointer;
   196     
   196 
   197     
   197 
   198     // detect the file format, as written in the first 4 bytes of the header
   198     // detect the file format, as written in the first 4 bytes of the header
   199     fp = Fopen (filename, "rb");
   199     fp = Fopen (filename, "rb");
   200     if (fp == NULL) {
   200     if (fp == NULL) {
   201         fprintf(stderr,"(Bridge ERROR) - File %s not loaded\n", filename);
   201         fprintf(stderr,"(Bridge ERROR) - File %s not loaded\n", filename);
   202         return -3;
   202         return -3;
   229         return -6;
   229         return -6;
   230     }
   230     }
   231 
   231 
   232     // alGenBuffers happens here
   232     // alGenBuffers happens here
   233     sound_data = init_sound_el(filename);
   233     sound_data = init_sound_el(filename);
   234     
   234 
   235     if (AL_NO_ERROR != alGetError()) {
   235     if (AL_NO_ERROR != alGetError()) {
   236         fprintf(stderr,"(Bridge ERROR) - Failed to allocate memory for buffer %d\n", index);
   236         fprintf(stderr,"(Bridge ERROR) - Failed to allocate memory for buffer %d\n", index);
   237         free(data);
   237         free(data);
   238         return -5;
   238         return -5;
   239     }
   239     }
   240     
   240 
   241     // copy pcm data in one buffer and free it
   241     // copy pcm data in one buffer and free it
   242     alBufferData(sound_data.buffer, format, data, bitsize, freq);
   242     alBufferData(sound_data.buffer, format, data, bitsize, freq);
   243     free(data);
   243     free(data);
   244 
   244 
   245     if (AL_NO_ERROR != alGetError()) {
   245     if (AL_NO_ERROR != alGetError()) {
   246         fprintf(stderr,"(Bridge ERROR) - Failed to write data to buffer %d\n", index);
   246         fprintf(stderr,"(Bridge ERROR) - Failed to write data to buffer %d\n", index);
   247         return -8;
   247         return -8;
   248     }
   248     }
   249     
   249 
   250     // clear any AL errors beforehand
   250     // clear any AL errors beforehand
   251     alGetError();
   251     alGetError();
   252 
   252 
   253     fprintf(stderr,"(Bridge Info) - successfully loaded %s\n", filename);
   253     fprintf(stderr,"(Bridge Info) - successfully loaded %s\n", filename);
   254 
   254 
   263 
   263 
   264     if (openal_ready() == AL_TRUE && index < cache_size && the_sounds[index].is_used == AL_TRUE) {
   264     if (openal_ready() == AL_TRUE && index < cache_size && the_sounds[index].is_used == AL_TRUE) {
   265         alGetSourcei (Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state);
   265         alGetSourcei (Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state);
   266         if (state == AL_PLAYING || state == AL_PAUSED)
   266         if (state == AL_PLAYING || state == AL_PAUSED)
   267             openal_stopsound(index);
   267             openal_stopsound(index);
   268         
   268 
   269         // free memory and 
   269         // free memory and
   270         alDeleteBuffers (1, &the_sounds[index].buffer);
   270         alDeleteBuffers (1, &the_sounds[index].buffer);
   271         the_sounds[index] = new_sound_el();
   271         the_sounds[index] = new_sound_el();
   272     }
   272     }
   273 }
   273 }