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