Rev 171 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 171 | Rev 181 | ||
---|---|---|---|
Line 40... | Line 40... | ||
40 | // global variables used in this module only |
40 | // global variables used in this module only |
41 | static ALCdevice *openal_device; |
41 | static ALCdevice *openal_device; |
42 | static ALCcontext *openal_context; |
42 | static ALCcontext *openal_context; |
43 | static openal_buffer_t *soundbuffers; // mallocated linked list |
43 | static openal_buffer_t *soundbuffers; // mallocated linked list |
44 | static openal_source_t *sources; // mallocated |
44 | static openal_source_t *sources; // mallocated |
45 | static enqueued_sound_t |
45 | static enqueued_sound_t enqueued_sounds[8]; |
- | 46 | static int enqueued_sound_count = 0; |
|
46 | static int source_count; |
47 | static int source_count; |
47 | 48 | ||
48 | 49 | ||
49 | bool Audio_Init (void) |
50 | bool Audio_Init (void) |
50 | { |
51 | { |
Line 64... | Line 65... | ||
64 | soundbuffers = NULL; // we know no soundbuffer yet |
65 | soundbuffers = NULL; // we know no soundbuffer yet |
65 | 66 | ||
66 | sources = NULL; // we have no playing source yet |
67 | sources = NULL; // we have no playing source yet |
67 | source_count = 0; |
68 | source_count = 0; |
68 | 69 | ||
- | 70 | memset (enqueued_sounds, 0, sizeof (enqueued_sounds)); |
|
69 |
|
71 | enqueued_sound_count = 0; // no sound is enqueued yet |
70 | 72 | ||
71 | return (true); // audio subsystem successfully initialized |
73 | return (true); // audio subsystem successfully initialized |
72 | } |
74 | } |
73 | 75 | ||
74 | 76 | ||
Line 120... | Line 122... | ||
120 | { |
122 | { |
121 | // this function enqueues sounds, plays them and disposes of sound buffers and sources that have finished playing |
123 | // this function enqueues sounds, plays them and disposes of sound buffers and sources that have finished playing |
122 | 124 | ||
123 | static wchar_t soundfile_path[MAX_PATH]; |
125 | static wchar_t soundfile_path[MAX_PATH]; |
124 | 126 | ||
125 | enqueued_sound_t processed_sound; |
127 | enqueued_sound_t *processed_sound; |
126 | openal_buffer_t *soundbuffer; |
128 | openal_buffer_t *soundbuffer; |
127 | ALfloat camera_position[3]; |
129 | ALfloat camera_position[3]; |
128 | ALfloat forward_and_up[6]; |
130 | ALfloat forward_and_up[6]; |
129 | unsigned long current_pos; |
131 | unsigned long current_pos; |
130 | buffer_t soundfile; |
132 | buffer_t soundfile; |
Line 135... | Line 137... | ||
135 | int sample_rate; |
137 | int sample_rate; |
136 | int channel_count; |
138 | int channel_count; |
137 | int channel_index; |
139 | int channel_index; |
138 | int channel_size; |
140 | int channel_size; |
139 | int source_index; |
141 | int source_index; |
- | 142 | int sound_index; |
|
140 | uint32_t chunk_id; |
143 | uint32_t chunk_id; |
141 | uint32_t blksiz; |
144 | uint32_t blksiz; |
142 | uint32_t temp32; |
145 | uint32_t temp32; |
143 | uint16_t temp16; |
146 | uint16_t temp16; |
144 | ALint status; |
147 | ALint status; |
Line 175... | Line 178... | ||
175 | // update the listener's position and orientation |
178 | // update the listener's position and orientation |
176 | alListener3f (AL_POSITION, camera_position[0], camera_position[1], camera_position[2]); |
179 | alListener3f (AL_POSITION, camera_position[0], camera_position[1], camera_position[2]); |
177 | alListener3f (AL_VELOCITY, 0, 0, 0); // TODO: compute velocity dynamically with previous position |
180 | alListener3f (AL_VELOCITY, 0, 0, 0); // TODO: compute velocity dynamically with previous position |
178 | alListenerfv (AL_ORIENTATION, forward_and_up); |
181 | alListenerfv (AL_ORIENTATION, forward_and_up); |
179 | 182 | ||
180 | // |
183 | // are there sounds enqueued for playing ? if so, process them one after the other |
181 |
|
184 | for (sound_index = 0; sound_index < enqueued_sound_count; sound_index++) |
182 | { |
185 | { |
183 |
|
186 | processed_sound = &enqueued_sounds[sound_index]; // quick access to enqueued sound |
184 | enqueued_sound.type = 0; // have a copy of it quickly and reset it (helps preserve thread safety) |
- | |
185 | 187 | ||
186 | // given the type of sound we want, enqueue the right one |
188 | // given the type of sound we want, enqueue the right one |
187 | pitch = 1.0f; // assume fixed pitch until told otherwise |
189 | pitch = 1.0f; // assume fixed pitch until told otherwise |
188 | if (processed_sound |
190 | if (processed_sound->type == SOUNDTYPE_CLICK) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/click.wav", app_path, theme->name); |
189 | else if (processed_sound |
191 | else if (processed_sound->type == SOUNDTYPE_ILLEGALMOVE) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/illegal.wav", app_path, theme->name); |
190 | else if (processed_sound |
192 | else if (processed_sound->type == SOUNDTYPE_VICTORY) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/win.wav", app_path, theme->name); |
191 | else if (processed_sound |
193 | else if (processed_sound->type == SOUNDTYPE_DEFEAT) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/lose.wav", app_path, theme->name); |
192 | else if (processed_sound |
194 | else if (processed_sound->type == SOUNDTYPE_CHECK) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/check.wav", app_path, theme->name); |
193 | else if (processed_sound |
195 | else if (processed_sound->type == SOUNDTYPE_PIECETAKEN) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/take.wav", app_path, theme->name); |
194 | else if (processed_sound |
196 | else if (processed_sound->type == SOUNDTYPE_HINTWINDOW) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/hintwindow.wav", app_path, theme->name); |
195 | else if (processed_sound |
197 | else if (processed_sound->type == SOUNDTYPE_IMPORTANT) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/important.wav", app_path, theme->name); |
196 | else if (processed_sound |
198 | else if (processed_sound->type == SOUNDTYPE_MOVE) |
197 | { |
199 | { |
198 | temp32 = rand () % 6; // there are several movement sounds, pick one at random |
200 | temp32 = rand () % 6; // there are several movement sounds, pick one at random |
199 | if (temp32 == 0) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move1.wav", app_path, theme->name); |
201 | if (temp32 == 0) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move1.wav", app_path, theme->name); |
200 | else if (temp32 == 1) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move2.wav", app_path, theme->name); |
202 | else if (temp32 == 1) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move2.wav", app_path, theme->name); |
201 | else if (temp32 == 2) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move3.wav", app_path, theme->name); |
203 | else if (temp32 == 2) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move3.wav", app_path, theme->name); |
202 | else if (temp32 == 3) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move4.wav", app_path, theme->name); |
204 | else if (temp32 == 3) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move4.wav", app_path, theme->name); |
203 | else if (temp32 == 4) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move5.wav", app_path, theme->name); |
205 | else if (temp32 == 4) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move5.wav", app_path, theme->name); |
204 | else swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move6.wav", app_path, theme->name); |
206 | else swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move6.wav", app_path, theme->name); |
205 | pitch = 1.0f + ((((float) rand ()) / RAND_MAX) - 0.5f) / 2.0f; // set a random pitch for these sounds between 0.75 and 1.25 |
207 | pitch = 1.0f + ((((float) rand ()) / RAND_MAX) - 0.5f) / 2.0f; // set a random pitch for these sounds between 0.75 and 1.25 |
206 | } |
208 | } |
207 | else if (processed_sound |
209 | else if (processed_sound->type == SOUNDTYPE_SLIDE) |
208 | { |
210 | { |
209 | swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/slide.wav", app_path, theme->name); |
211 | swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/slide.wav", app_path, theme->name); |
210 | pitch = 1.0f + ((((float) rand ()) / RAND_MAX) - 0.5f) / 2.0f; // set a random pitch for these sounds between 0.75 and 1.25 |
212 | pitch = 1.0f + ((((float) rand ()) / RAND_MAX) - 0.5f) / 2.0f; // set a random pitch for these sounds between 0.75 and 1.25 |
211 | } |
213 | } |
212 | 214 | ||
Line 331... | Line 333... | ||
331 | sources[source_index].is_used = true; // immediately mark it as used |
333 | sources[source_index].is_used = true; // immediately mark it as used |
332 | alGenSources (1, &sources[source_index].openal_source); // (re)create an OpenAL source |
334 | alGenSources (1, &sources[source_index].openal_source); // (re)create an OpenAL source |
333 | 335 | ||
334 | alSourcef (sources[source_index].openal_source, AL_PITCH, (ALfloat) pitch); // set the source's pitch |
336 | alSourcef (sources[source_index].openal_source, AL_PITCH, (ALfloat) pitch); // set the source's pitch |
335 | alSourcef (sources[source_index].openal_source, AL_GAIN, 1.0f); // set the source's volume (full) |
337 | alSourcef (sources[source_index].openal_source, AL_GAIN, 1.0f); // set the source's volume (full) |
336 | alSource3f (sources[source_index].openal_source, AL_POSITION, (ALfloat) processed_sound |
338 | alSource3f (sources[source_index].openal_source, AL_POSITION, (ALfloat) processed_sound->emitterlocation_x * ATTENUATION_FACTOR, (ALfloat) processed_sound->emitterlocation_y * ATTENUATION_FACTOR, (ALfloat) processed_sound->emitterlocation_z * ATTENUATION_FACTOR); |
337 | alSource3f (sources[source_index].openal_source, AL_VELOCITY, 0, 0, 0); // set the source's velocity (static) |
339 | alSource3f (sources[source_index].openal_source, AL_VELOCITY, 0, 0, 0); // set the source's velocity (static) |
338 | alSourcei (sources[source_index].openal_source, AL_LOOPING, AL_FALSE); // set it as non-looping |
340 | alSourcei (sources[source_index].openal_source, AL_LOOPING, AL_FALSE); // set it as non-looping |
339 | alSourcei (sources[source_index].openal_source, AL_BUFFER, soundbuffer->openal_buffer); // attach our bufferized data to it |
341 | alSourcei (sources[source_index].openal_source, AL_BUFFER, soundbuffer->openal_buffer); // attach our bufferized data to it |
340 | 342 | ||
341 | // play the source! Audio_Think() will dispose of it when it's finished |
343 | // play the source! Audio_Think() will dispose of it when it's finished |
342 | alSourcePlay (sources[source_index].openal_source); |
344 | alSourcePlay (sources[source_index].openal_source); |
343 | } |
345 | } |
- | 346 | ||
- | 347 | enqueued_sound_count = 0; // after that, remember that all enqueued sounds have been sent to OpenAL |
|
344 | 348 | ||
345 | // cycle through all used sources and see if one is no longer playing |
349 | // cycle through all used sources and see if one is no longer playing |
346 | for (source_index = 0; source_index < source_count; source_index++) |
350 | for (source_index = 0; source_index < source_count; source_index++) |
347 | { |
351 | { |
348 | if (!sources[source_index].is_used) |
352 | if (!sources[source_index].is_used) |
Line 363... | Line 367... | ||
363 | 367 | ||
364 | void Audio_PlaySound (int sound_type, float pos_x, float pos_y, float pos_z) |
368 | void Audio_PlaySound (int sound_type, float pos_x, float pos_y, float pos_z) |
365 | { |
369 | { |
366 | // helper function to play a sound (WARNING: it is NOT thread-safe!) |
370 | // helper function to play a sound (WARNING: it is NOT thread-safe!) |
367 | 371 | ||
368 | if (!options.want_sounds) |
372 | if (!options.want_sounds || (enqueued_sound_count == sizeof (enqueued_sounds) / sizeof (enqueued_sounds[0]))) |
369 | return; // if we want no |
373 | return; // if we want no sound OR if there's no space to add one, don't play anything |
370 | 374 | ||
371 |
|
375 | enqueued_sounds[enqueued_sound_count].type = sound_type; // enqueue this sound for playing. Audio_Think() will take care of it. |
372 |
|
376 | enqueued_sounds[enqueued_sound_count].emitterlocation_x = pos_x; |
373 |
|
377 | enqueued_sounds[enqueued_sound_count].emitterlocation_y = pos_y; |
374 |
|
378 | enqueued_sounds[enqueued_sound_count].emitterlocation_z = pos_z; |
- | 379 | enqueued_sound_count++; // there's now one more sound to play |
|
375 | 380 | ||
376 | return; // finished |
381 | return; // finished |
377 | } |
382 | } |