27 // Buffers hold sound data. |
27 // Buffers hold sound data. |
28 ALuint *Buffers; |
28 ALuint *Buffers; |
29 //index for Sources and Buffers |
29 //index for Sources and Buffers |
30 ALuint globalindex, globalsize; |
30 ALuint globalindex, globalsize; |
31 // Position of the source sound. |
31 // Position of the source sound. |
32 ALfloat **SourcePos; |
32 ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; |
33 // Velocity of the source sound. |
33 // Velocity of the source sound. |
34 ALfloat **SourceVel; |
34 ALfloat SourceVel[] = { 0.0, 0.0, 0.0 }; |
35 |
35 |
|
36 int increment; |
36 |
37 |
37 ALint openal_close(void) { |
38 ALint openal_close(void) { |
38 /* This function stops all the sounds, deallocates all memory and closes OpenAL */ |
39 /* This function stops all the sounds, deallocates all memory and closes OpenAL */ |
39 int i; |
|
40 ALCcontext *context; |
40 ALCcontext *context; |
41 ALCdevice *device; |
41 ALCdevice *device; |
42 |
42 |
43 alSourceStopv (globalsize, Sources); |
43 alSourceStopv (globalsize, Sources); |
44 alDeleteSources (globalsize, Sources); |
44 alDeleteSources (globalsize, Sources); |
45 alDeleteBuffers (globalsize, Buffers); |
45 alDeleteBuffers (globalsize, Buffers); |
46 |
46 |
47 for (i = 0; i < globalsize; i++) { |
|
48 free(SourcePos[i]); |
|
49 free(SourceVel[i]); |
|
50 } |
|
51 free(SourcePos); |
|
52 free(SourceVel); |
|
53 free(Sources); |
47 free(Sources); |
54 free(Buffers); |
48 free(Buffers); |
55 |
49 |
56 context = alcGetCurrentContext(); |
50 context = alcGetCurrentContext(); |
57 device = alcGetContextsDevice(context); |
51 device = alcGetContextsDevice(context); |
65 |
59 |
66 ALint openal_init(int memorysize) { |
60 ALint openal_init(int memorysize) { |
67 /* This function initializes an OpenAL contex, allocates memory space for data and prepares OpenAL buffers*/ |
61 /* This function initializes an OpenAL contex, allocates memory space for data and prepares OpenAL buffers*/ |
68 ALCcontext *context; |
62 ALCcontext *context; |
69 ALCdevice *device; |
63 ALCdevice *device; |
70 |
|
71 const ALCchar *default_device; |
64 const ALCchar *default_device; |
|
65 |
72 // Position of the listener. |
66 // Position of the listener. |
73 ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 }; |
67 ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 }; |
74 // Velocity of the listener. |
68 // Velocity of the listener. |
75 ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 }; |
69 ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 }; |
76 // Orientation of the listener. (first 3 elements are "at", second 3 are "up") |
70 // Orientation of the listener. (first 3 elements are "at", second 3 are "up") |
77 ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; |
71 ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; |
78 |
72 |
79 default_device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); |
73 default_device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); |
80 |
|
81 fprintf(stderr, "Using default device: %s\n", default_device); |
74 fprintf(stderr, "Using default device: %s\n", default_device); |
82 |
75 |
83 if ((device = alcOpenDevice(default_device)) == NULL) { |
76 if ((device = alcOpenDevice(default_device)) == NULL) { |
84 fprintf(stderr, "ERROR: Failed to open sound device\n"); |
77 fprintf(stderr, "ERROR: Failed to open sound device\n"); |
85 return AL_FALSE; |
78 return AL_FALSE; |
86 } |
79 } |
|
80 |
87 context = alcCreateContext(device, NULL); |
81 context = alcCreateContext(device, NULL); |
88 alcMakeContextCurrent(context); |
82 alcMakeContextCurrent(context); |
89 alcProcessContext(context); |
83 alcProcessContext(context); |
90 |
84 |
91 if (AlGetError("ERROR %d: Creating a new contex\n") != AL_TRUE) |
85 if (AlGetError("ERROR %d: Creating a new contex\n") != AL_TRUE) |
92 return AL_FALSE; |
86 return AL_FALSE; |
93 |
87 |
94 //allocate memory space for buffers and sources |
88 //allocate memory space for buffers and sources |
95 globalsize = memorysize; |
89 globalsize = memorysize; |
96 Buffers = (ALuint*) Malloc(sizeof(ALuint )*globalsize); |
90 increment = memorysize; |
97 Sources = (ALuint*) Malloc(sizeof(ALuint )*globalsize); |
91 Buffers = (ALuint*) Malloc(sizeof(ALuint)*globalsize); |
98 SourcePos = (ALfloat**) Malloc(sizeof(ALfloat*)*globalsize); |
92 Sources = (ALuint*) Malloc(sizeof(ALuint)*globalsize); |
99 SourceVel = (ALfloat**) Malloc(sizeof(ALfloat*)*globalsize); |
|
100 |
93 |
101 //set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation |
94 //set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation |
102 alListenerf (AL_GAIN, 1.0f ); |
95 alListenerf (AL_GAIN, 1.0f ); |
103 alListenerfv(AL_POSITION, ListenerPos); |
96 alListenerfv(AL_POSITION, ListenerPos); |
104 alListenerfv(AL_VELOCITY, ListenerVel); |
97 alListenerfv(AL_VELOCITY, ListenerVel); |
107 if (AlGetError("ERROR %d: Setting Listener properties\n") != AL_TRUE) |
100 if (AlGetError("ERROR %d: Setting Listener properties\n") != AL_TRUE) |
108 return AL_FALSE; |
101 return AL_FALSE; |
109 |
102 |
110 alGetError(); /* clear any AL errors beforehand */ |
103 alGetError(); /* clear any AL errors beforehand */ |
111 return AL_TRUE; |
104 return AL_TRUE; |
|
105 } |
|
106 |
|
107 int helper_realloc (void) { |
|
108 globalsize += increment; |
|
109 #ifdef DEBUG |
|
110 fprintf(stderr, "OpenAL: Realloc in process %d\n", globalsize); |
|
111 #endif |
|
112 Buffers = (ALuint*) reallocf(Buffers, sizeof(ALuint)*globalsize); |
|
113 Sources = (ALuint*) reallocf(Sources, sizeof(ALuint)*globalsize); |
|
114 if (Buffers == NULL || Sources == NULL) { |
|
115 fprintf(stderr, "ERROR: not enough memory! realloc() failed\n"); |
|
116 exit(-1); |
|
117 } else { |
|
118 return 0; |
|
119 } |
112 } |
120 } |
113 |
121 |
114 |
122 |
115 int openal_loadfile (const char *filename){ |
123 int openal_loadfile (const char *filename){ |
116 /* This function opens a file, loads into memory and allocates the Source buffer for playing*/ |
124 /* This function opens a file, loads into memory and allocates the Source buffer for playing*/ |
117 ALenum format; |
125 ALenum format; |
118 ALsizei bitsize; |
126 ALsizei bitsize; |
119 ALsizei freq; |
127 ALsizei freq; |
120 uint8_t *data; |
128 uint8_t *data; |
121 uint32_t fileformat; |
129 uint32_t fileformat; |
122 int i, error; |
130 int error; |
123 FILE *fp; |
131 FILE *fp; |
124 |
132 |
|
133 |
|
134 if (globalindex == globalsize) |
|
135 helper_realloc(); |
125 |
136 |
126 /*detect the file format, as written in the first 4 bytes of the header*/ |
137 /*detect the file format, as written in the first 4 bytes of the header*/ |
127 fp = Fopen (filename, "rb"); |
138 fp = Fopen (filename, "rb"); |
128 if (fp == NULL) |
139 if (fp == NULL) |
129 return -1; |
140 return -1; |
163 alBufferData(Buffers[globalindex], format, data, bitsize, freq); |
174 alBufferData(Buffers[globalindex], format, data, bitsize, freq); |
164 free(data); //deallocate data to save memory |
175 free(data); //deallocate data to save memory |
165 |
176 |
166 if (AlGetError("ERROR %d: Writing data to buffer\n") != AL_TRUE) |
177 if (AlGetError("ERROR %d: Writing data to buffer\n") != AL_TRUE) |
167 return -6; |
178 return -6; |
168 |
|
169 //memory allocation for source position and velocity |
|
170 SourcePos[globalindex] = (ALfloat*) Malloc(sizeof(ALfloat)*3); |
|
171 SourceVel[globalindex] = (ALfloat*) Malloc(sizeof(ALfloat)*3); |
|
172 |
|
173 if (SourcePos[globalindex] == NULL || SourceVel[globalindex] == NULL) |
|
174 return -7; |
|
175 |
179 |
176 //source properties that it will use when it's in playback |
180 //source properties that it will use when it's in playback |
177 for (i = 0; i < 3; i++) { |
|
178 SourcePos[globalindex][i] = 0.0; |
|
179 SourceVel[globalindex][i] = 0.1; |
|
180 } |
|
181 alSourcei (Sources[globalindex], AL_BUFFER, Buffers[globalindex] ); |
181 alSourcei (Sources[globalindex], AL_BUFFER, Buffers[globalindex] ); |
182 alSourcef (Sources[globalindex], AL_PITCH, 1.0f ); |
182 alSourcef (Sources[globalindex], AL_PITCH, 1.0f ); |
183 alSourcef (Sources[globalindex], AL_GAIN, 1.0f ); |
183 alSourcef (Sources[globalindex], AL_GAIN, 1.0f ); |
184 alSourcefv(Sources[globalindex], AL_POSITION, SourcePos[globalindex]); |
184 alSourcefv(Sources[globalindex], AL_POSITION, SourcePos ); |
185 alSourcefv(Sources[globalindex], AL_VELOCITY, SourceVel[globalindex]); |
185 alSourcefv(Sources[globalindex], AL_VELOCITY, SourceVel ); |
186 alSourcei (Sources[globalindex], AL_LOOPING, 0 ); |
186 alSourcei (Sources[globalindex], AL_LOOPING, 0 ); |
187 |
187 |
188 if (AlGetError("ERROR %d: Setting source properties\n") != AL_TRUE) |
188 if (AlGetError("ERROR %d: Setting source properties\n") != AL_TRUE) |
189 return -8; |
189 return -7; |
190 |
190 |
191 alGetError(); /* clear any AL errors beforehand */ |
191 alGetError(); /* clear any AL errors beforehand */ |
192 |
192 |
193 //returns the index of the source you just loaded, increments it and exits |
193 //returns the index of the source you just loaded, increments it and exits |
194 return globalindex++; |
194 return globalindex++; |
198 ALint openal_toggleloop (int index){ |
198 ALint openal_toggleloop (int index){ |
199 /*Set or unset looping mode*/ |
199 /*Set or unset looping mode*/ |
200 ALint loop; |
200 ALint loop; |
201 |
201 |
202 if (index >= globalsize) { |
202 if (index >= globalsize) { |
203 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex); |
203 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)\n", index, globalindex); |
204 return AL_FALSE; |
204 return AL_FALSE; |
205 } |
205 } |
206 |
206 |
207 alGetSourcei (Sources[index], AL_LOOPING, &loop); |
207 alGetSourcei (Sources[index], AL_LOOPING, &loop); |
208 alSourcei (Sources[index], AL_LOOPING, !((uint8_t) loop) & 0x00000001); |
208 alSourcei (Sources[index], AL_LOOPING, !((uint8_t) loop) & 0x00000001); |
264 alGetError(); /* clear any AL errors beforehand */ |
264 alGetError(); /* clear any AL errors beforehand */ |
265 |
265 |
266 return AL_TRUE; |
266 return AL_TRUE; |
267 } |
267 } |
268 |
268 |
269 |
269 |
270 ALint openal_fadeout(int index, unsigned int quantity) { |
270 ALint openal_fade(int index, unsigned int quantity, char inout) { |
271 #ifndef _WIN32 |
271 #ifndef _WIN32 |
272 pthread_t thread; |
272 pthread_t thread; |
273 #else |
273 #else |
274 HANDLE Thread; |
274 HANDLE Thread; |
275 DWORD threadID; |
275 DWORD threadID; |
276 #endif |
276 #endif |
277 fade_t *fade; |
277 fade_t *fade; |
278 |
|
279 if (index >= globalindex) { |
|
280 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex); |
|
281 return AL_FALSE; |
|
282 } |
|
283 |
278 |
284 fade = (fade_t*) Malloc(sizeof(fade_t)); |
279 fade = (fade_t*) Malloc(sizeof(fade_t)); |
285 fade->index = index; |
280 fade->index = index; |
286 fade->quantity = quantity; |
281 fade->quantity = quantity; |
287 |
282 |
|
283 if (index >= globalindex) { |
|
284 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)\n", index, globalindex); |
|
285 return AL_FALSE; |
|
286 } |
|
287 |
|
288 if (inout == FADE_IN) |
288 #ifndef _WIN32 |
289 #ifndef _WIN32 |
289 pthread_create(&thread, NULL, helper_fadeout, (void*) fade); |
290 pthread_create(&thread, NULL, helper_fadein, (void*) fade); |
|
291 #else |
|
292 Thread = _beginthread(&helper_fadein, 0, (void*) fade); |
|
293 #endif |
|
294 else { |
|
295 if (inout == FADE_OUT) |
|
296 #ifndef _WIN32 |
|
297 pthread_create(&thread, NULL, helper_fadeout, (void*) fade); |
|
298 #else |
|
299 Thread = _beginthread(&helper_fadeout, 0, (void*) fade); |
|
300 #endif |
|
301 else { |
|
302 fprintf(stderr, "ERROR: unknown direction for fade (%d)\n", inout); |
|
303 free(fade); |
|
304 return AL_FALSE; |
|
305 } |
|
306 } |
|
307 |
|
308 #ifndef _WIN32 |
290 pthread_detach(thread); |
309 pthread_detach(thread); |
291 #else |
310 #endif |
292 Thread = _beginthread(&helper_fadeout, 0, (void*) fade); |
311 |
293 #endif |
312 alGetError(); /* clear any AL errors beforehand */ |
294 |
313 |
295 alGetError(); /* clear any AL errors beforehand */ |
314 return AL_TRUE; |
296 |
315 } |
297 return AL_TRUE; |
316 |
|
317 |
|
318 ALint openal_fadeout(int index, unsigned int quantity) { |
|
319 return openal_fade(index, quantity, FADE_OUT); |
298 } |
320 } |
299 |
321 |
300 |
322 |
301 ALint openal_fadein(int index, unsigned int quantity) { |
323 ALint openal_fadein(int index, unsigned int quantity) { |
302 #ifndef _WIN32 |
324 return openal_fade(index, quantity, FADE_IN); |
303 pthread_t thread; |
325 } |
304 #else |
326 |
305 HANDLE Thread; |
|
306 DWORD threadID; |
|
307 #endif |
|
308 fade_t *fade; |
|
309 |
|
310 fade = (fade_t*) Malloc(sizeof(fade_t)); |
|
311 fade->index = index; |
|
312 fade->quantity = quantity; |
|
313 |
|
314 if (index >= globalindex) { |
|
315 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex); |
|
316 return AL_FALSE; |
|
317 } |
|
318 |
|
319 #ifndef _WIN32 |
|
320 pthread_create(&thread, NULL, helper_fadein, (void*) fade); |
|
321 pthread_detach(thread); |
|
322 #else |
|
323 Thread = _beginthread(&helper_fadein, 0, (void*) fade); |
|
324 #endif |
|
325 |
|
326 alGetError(); /* clear any AL errors beforehand */ |
|
327 |
|
328 return AL_TRUE; |
|
329 } |
|
330 |
|
331 |
327 |
332 ALint openal_playsound(int index){ |
328 ALint openal_playsound(int index){ |
333 /*Play sound number index*/ |
329 /*Play sound number index*/ |
334 if (index >= globalindex) { |
330 if (index >= globalindex) { |
335 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex); |
331 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)\n", index, globalindex); |
336 return AL_FALSE; |
332 return AL_FALSE; |
337 } |
333 } |
338 alSourcePlay(Sources[index]); |
334 alSourcePlay(Sources[index]); |
339 if (AlGetError("ERROR %d: Playing last sound\n") != AL_TRUE) |
335 if (AlGetError("ERROR %d: Playing last sound\n") != AL_TRUE) |
340 return AL_FALSE; |
336 return AL_FALSE; |
346 |
342 |
347 |
343 |
348 ALint openal_pausesound(int index){ |
344 ALint openal_pausesound(int index){ |
349 /*Pause sound number index*/ |
345 /*Pause sound number index*/ |
350 if (index >= globalindex) { |
346 if (index >= globalindex) { |
351 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex); |
347 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)\n", index, globalindex); |
352 return AL_FALSE; |
348 return AL_FALSE; |
353 } |
349 } |
354 alSourcePause(Sources[index]); |
350 alSourcePause(Sources[index]); |
355 if (AlGetError("ERROR %d: Pausing last sound\n") != AL_TRUE) |
351 if (AlGetError("ERROR %d: Pausing last sound\n") != AL_TRUE) |
356 return AL_FALSE; |
352 return AL_FALSE; |
360 |
356 |
361 |
357 |
362 ALint openal_stopsound(int index){ |
358 ALint openal_stopsound(int index){ |
363 /*Stop sound number index*/ |
359 /*Stop sound number index*/ |
364 if (index >= globalindex) { |
360 if (index >= globalindex) { |
365 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)", index, globalindex); |
361 fprintf(stderr, "ERROR: index out of bounds (got %d, max %d)\n", index, globalindex); |
366 return AL_FALSE; |
362 return AL_FALSE; |
367 } |
363 } |
368 alSourceStop(Sources[index]); |
364 alSourceStop(Sources[index]); |
369 if (AlGetError("ERROR %d: Stopping last sound\n") != AL_TRUE) |
365 if (AlGetError("ERROR %d: Stopping last sound\n") != AL_TRUE) |
370 return AL_FALSE; |
366 return AL_FALSE; |