Subversion Repositories Games.Chess Giants

Rev

Rev 136 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 136 Rev 171
Line 10... Line 10...
10
// attenuation factor (lower means sounds fade LESS with distance, higher means sounds fade MORE with distance)
10
// attenuation factor (lower means sounds fade LESS with distance, higher means sounds fade MORE with distance)
11
#define ATTENUATION_FACTOR 0.02f
11
#define ATTENUATION_FACTOR 0.02f
12
 
12
 
13
 
13
 
14
// structures used in this module only
14
// structures used in this module only
-
 
15
typedef struct enqueued_sound_s
-
 
16
{
-
 
17
   int type;
-
 
18
   float emitterlocation_x;
-
 
19
   float emitterlocation_y;
-
 
20
   float emitterlocation_z;
-
 
21
} enqueued_sound_t;
-
 
22
 
-
 
23
 
15
typedef struct openal_buffer_s
24
typedef struct openal_buffer_s
16
{
25
{
17
   wchar_t *pathname; // sound pathname (mallocated, if NULL then slot is empty)
26
   wchar_t *pathname; // sound pathname (mallocated, if NULL then slot is empty)
18
   ALshort *openal_samples; // OpenAL samples (16-bit mono)
27
   ALshort *openal_samples; // OpenAL samples (16-bit mono)
19
   ALuint openal_buffer; // associated OpenAL buffer ID
28
   ALuint openal_buffer; // associated OpenAL buffer ID
Line 31... Line 40...
31
// global variables used in this module only
40
// global variables used in this module only
32
static ALCdevice *openal_device;
41
static ALCdevice *openal_device;
33
static ALCcontext *openal_context;
42
static ALCcontext *openal_context;
34
static openal_buffer_t *soundbuffers; // mallocated linked list
43
static openal_buffer_t *soundbuffers; // mallocated linked list
35
static openal_source_t *sources; // mallocated
44
static openal_source_t *sources; // mallocated
-
 
45
static enqueued_sound_t enqueued_sound;
36
static int source_count;
46
static int source_count;
-
 
47
 
37
 
48
 
38
bool Audio_Init (void)
49
bool Audio_Init (void)
39
{
50
{
40
   // this function initializes the audio subsystem (OpenAL)
51
   // this function initializes the audio subsystem (OpenAL)
41
 
52
 
Line 52... Line 63...
52
 
63
 
53
   soundbuffers = NULL; // we know no soundbuffer yet
64
   soundbuffers = NULL; // we know no soundbuffer yet
54
 
65
 
55
   sources = NULL; // we have no playing source yet
66
   sources = NULL; // we have no playing source yet
56
   source_count = 0;
67
   source_count = 0;
-
 
68
 
-
 
69
   enqueued_sound.type = 0; // no sound is enqueued yet
57
 
70
 
58
   return (true); // audio subsystem successfully initialized
71
   return (true); // audio subsystem successfully initialized
59
}
72
}
60
 
73
 
61
 
74
 
Line 103... Line 116...
103
}
116
}
104
 
117
 
105
 
118
 
106
void Audio_Think (void)
119
void Audio_Think (void)
107
{
120
{
108
   // this function disposes of sound buffers and sources that have finished playing
121
   // this function enqueues sounds, plays them and disposes of sound buffers and sources that have finished playing
109
 
122
 
-
 
123
   static wchar_t soundfile_path[MAX_PATH];
-
 
124
 
-
 
125
   enqueued_sound_t processed_sound;
-
 
126
   openal_buffer_t *soundbuffer;
-
 
127
   ALfloat camera_position[3];
-
 
128
   ALfloat forward_and_up[6];
-
 
129
   unsigned long current_pos;
-
 
130
   buffer_t soundfile;
-
 
131
   int sample_value;
-
 
132
   int sample_count;
-
 
133
   int sample_index;
-
 
134
   int sample_size;
-
 
135
   int sample_rate;
-
 
136
   int channel_count;
-
 
137
   int channel_index;
-
 
138
   int channel_size;
110
   int source_index;
139
   int source_index;
-
 
140
   uint32_t chunk_id;
-
 
141
   uint32_t blksiz;
-
 
142
   uint32_t temp32;
-
 
143
   uint16_t temp16;
111
   ALint status;
144
   ALint status;
112
   float angle;
145
   float angle;
113
   float sin_pitch;
146
   float sin_pitch;
114
   float sin_yaw;
147
   float sin_yaw;
115
   float cos_pitch;
148
   float cos_pitch;
116
   float cos_yaw;
149
   float cos_yaw;
117
   ALfloat camera_position[3];
150
   float pitch;
118
   ALfloat forward_and_up[6];
-
 
119
 
151
 
120
   // compute the sine and cosine of the pitch component
152
   // compute the sine and cosine of the pitch component
121
   angle = current_pitch * TO_RADIANS;
153
   angle = current_pitch * TO_RADIANS;
122
   sin_pitch = sinf (angle);
154
   sin_pitch = sinf (angle);
123
   cos_pitch = cosf (angle);
155
   cos_pitch = cosf (angle);
Line 143... Line 175...
143
   // update the listener's position and orientation
175
   // update the listener's position and orientation
144
   alListener3f (AL_POSITION, camera_position[0], camera_position[1], camera_position[2]);
176
   alListener3f (AL_POSITION, camera_position[0], camera_position[1], camera_position[2]);
145
   alListener3f (AL_VELOCITY, 0, 0, 0); // TODO: compute velocity dynamically with previous position
177
   alListener3f (AL_VELOCITY, 0, 0, 0); // TODO: compute velocity dynamically with previous position
146
   alListenerfv (AL_ORIENTATION, forward_and_up);
178
   alListenerfv (AL_ORIENTATION, forward_and_up);
147
 
179
 
148
   // cycle through all used sources and see if one is no longer playing
180
   // is one sound enqueued for playing ?
149
   for (source_index = 0; source_index < source_count; source_index++)
181
   if (enqueued_sound.type != 0)
150
   {
182
   {
151
      if (!sources[source_index].is_used)
183
      memcpy (&processed_sound, &enqueued_sound, sizeof (enqueued_sound_t));
152
         continue; // skip unused slots
184
      enqueued_sound.type = 0; // have a copy of it quickly and reset it (helps preserve thread safety)
153
 
185
 
-
 
186
      // given the type of sound we want, enqueue the right one
-
 
187
      pitch = 1.0f; // assume fixed pitch until told otherwise
-
 
188
      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.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.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.type == SOUNDTYPE_DEFEAT)      swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/lose.wav", app_path, theme->name);
154
      alGetSourcei (sources[source_index].openal_source, AL_SOURCE_STATE, &status); // get this source's playing state
192
      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.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.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.type == SOUNDTYPE_IMPORTANT)   swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/important.wav", app_path, theme->name);
155
      if (status == AL_PLAYING)
196
      else if (processed_sound.type == SOUNDTYPE_MOVE)
-
 
197
      {
-
 
198
         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);
-
 
200
         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);
-
 
202
         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);
-
 
204
         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
-
 
206
      }
156
         continue; // skip sources that are still playing
207
      else if (processed_sound.type == SOUNDTYPE_SLIDE)
-
 
208
      {
-
 
209
         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
-
 
211
      }
157
 
212
 
158
      alSourcei (sources[source_index].openal_source, AL_BUFFER, NULL); // untie the buffer from this source
213
      // now cycle through our known OpenAL buffers and see if we already know this one
159
      alDeleteSources (1, &sources[source_index].openal_source); // and tell OpenAL to dispose of it
214
      for (soundbuffer = soundbuffers; soundbuffer != NULL; soundbuffer = soundbuffer->next)
-
 
215
         if ((soundbuffer->pathname != NULL) && (wcscmp (soundbuffer->pathname, soundfile_path) == 0))
160
      sources[source_index].is_used = false; // mark this source as unused now
216
            break; // break as soon as we find it
161
   }
-
 
162
 
217
 
163
   return; // finished, audio has been handled
218
      // have we NOT found it ? if so, we must create it
-
 
219
      if (soundbuffer == NULL)
164
}
220
      {
-
 
221
         // load the sound file
-
 
222
         Buffer_Initialize (&soundfile);
-
 
223
         if (!Buffer_ReadFromFileW (&soundfile, soundfile_path))
-
 
224
            return; // if unable to load this sound file, give up (FIXME: log something ?)
165
 
225
 
-
 
226
         // parse the WAV file
-
 
227
         sample_count = channel_count = sample_size = channel_size = 0;
-
 
228
         current_pos = 0;
-
 
229
         for (;;)
-
 
230
         {
-
 
231
#define READ_DATA(type) *((type *) &soundfile.data[current_pos]); current_pos += sizeof (type); if (current_pos >= soundfile.size) break;
166
 
232
 
-
 
233
            chunk_id = READ_DATA (uint32_t);
-
 
234
            if (chunk_id == *((uint32_t *) "RIFF"))
-
 
235
            {
167
void Audio_PlaySound (int sound_type, float pos_x, float pos_y, float pos_z)
236
               temp32 = READ_DATA (uint32_t); // skip the "chunk size" field
-
 
237
               temp32 = READ_DATA (uint32_t); // skip the "riff style" field (typically "WAVE")
-
 
238
            }
-
 
239
            else if (chunk_id == *((uint32_t *) "fmt "))
168
{
240
            {
-
 
241
               blksiz = READ_DATA (uint32_t);
-
 
242
               temp16 = READ_DATA (uint16_t); if (temp16 != 1) break; // compressed WAVs are unsupported
-
 
243
               temp32 = READ_DATA (uint16_t); channel_count = (int) temp16;
-
 
244
               temp32 = READ_DATA (uint32_t); sample_rate = (int) temp32;
-
 
245
               temp32 = READ_DATA (uint32_t);
-
 
246
               temp16 = READ_DATA (uint16_t); sample_size = (int) temp16;
-
 
247
               temp16 = READ_DATA (uint16_t); channel_size = (int) temp16 / 8;
-
 
248
               if (blksiz > 16)
169
   // helper function to play a sound
249
                  current_pos += blksiz - 16;
-
 
250
               if (current_pos >= soundfile.size)
-
 
251
                  break; // don't go beyond the end of the file
-
 
252
            }
-
 
253
            else if (chunk_id == *((uint32_t *) "data"))
-
 
254
            {
-
 
255
               temp32 = READ_DATA (uint32_t); sample_count = (int) temp32;
-
 
256
               break; // current_pos is now at the beginning of data, and data measures sample_count bytes long
-
 
257
            }
-
 
258
            else
-
 
259
            {
-
 
260
               blksiz = READ_DATA (uint32_t); // skip the "chunk size" field
-
 
261
               current_pos += blksiz; // useless chunk, skip it
-
 
262
               if (current_pos >= soundfile.size)
-
 
263
                  break; // don't go beyond the end of the file
-
 
264
            }
170
 
265
 
171
   static wchar_t soundfile_path[MAX_PATH];
-
 
172
   openal_buffer_t *soundbuffer;
-
 
173
   buffer_t soundfile;
-
 
174
   unsigned long current_pos;
-
 
175
   uint16_t temp16;
-
 
176
   uint32_t temp32;
-
 
177
   uint32_t blksiz;
266
#undef READ_DATA
178
   uint32_t chunk_id;
-
 
179
   int sample_count;
-
 
180
   int sample_index;
-
 
181
   int sample_size;
267
         }
182
   int channel_count;
268
         if ((sample_count == 0) || (channel_count == 0) || (sample_size == 0) || (channel_size == 0))
183
   int channel_index;
-
 
184
   int channel_size;
-
 
185
   int sample_value;
-
 
186
   int sample_rate;
-
 
187
   int source_index;
269
            return; // FIXME: not a wav file
188
   float pitch;
-
 
189
 
270
 
190
   if (!options.want_sounds)
271
         // compute the total number of samples (number of channels * number of frames)
191
      return; // if we want no sound, don't play anything
272
         sample_count /= sample_size;
192
 
273
 
193
   // given the type of sound we want, enqueue the right one
-
 
194
   pitch = 1.0f; // assume fixed pitch until told otherwise
-
 
195
   if      (sound_type == SOUNDTYPE_CLICK)       swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/click.wav", app_path, theme->name);
-
 
196
   else if (sound_type == SOUNDTYPE_ILLEGALMOVE) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/illegal.wav", app_path, theme->name);
-
 
197
   else if (sound_type == SOUNDTYPE_VICTORY)     swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/win.wav", app_path, theme->name);
-
 
198
   else if (sound_type == SOUNDTYPE_DEFEAT)      swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/lose.wav", app_path, theme->name);
-
 
199
   else if (sound_type == SOUNDTYPE_CHECK)       swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/check.wav", app_path, theme->name);
-
 
200
   else if (sound_type == SOUNDTYPE_PIECETAKEN)  swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/take.wav", app_path, theme->name);
-
 
201
   else if (sound_type == SOUNDTYPE_MOVE)
-
 
202
   {
-
 
203
      temp32 = rand () % 6; // there are several movement sounds, pick one at random
-
 
204
      if      (temp32 == 0) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move1.wav", app_path, theme->name);
-
 
205
      else if (temp32 == 1) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move2.wav", app_path, theme->name);
-
 
206
      else if (temp32 == 2) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move3.wav", app_path, theme->name);
-
 
207
      else if (temp32 == 3) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move4.wav", app_path, theme->name);
-
 
208
      else if (temp32 == 4) swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move5.wav", app_path, theme->name);
-
 
209
      else                  swprintf_s (soundfile_path, WCHAR_SIZEOF (soundfile_path), L"%s/themes/%s/sounds/move6.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
-
 
211
   }
-
 
212
   else if (sound_type == SOUNDTYPE_SLIDE)
-
 
213
   {
-
 
214
      swprintf_s(soundfile_path, WCHAR_SIZEOF(soundfile_path), L"%s/themes/%s/sounds/slide.wav", app_path, theme->name);
-
 
215
      pitch = 1.0f + ((((float)rand()) / RAND_MAX) - 0.5f) / 2.0f; // set a random pitch for these sounds between 0.75 and 1.25
-
 
216
   }
-
 
217
 
-
 
218
   // now cycle through our known OpenAL buffers and see if we already know this one
274
         // allocate space for one more sound buffer, and tie it to the linked list
219
   for (soundbuffer = soundbuffers; soundbuffer != NULL; soundbuffer = soundbuffer->next)
-
 
220
      if ((soundbuffer->pathname != NULL) && (wcscmp (soundbuffer->pathname, soundfile_path) == 0))
-
 
221
         break; // break as soon as we find it
-
 
222
 
-
 
223
   // have we NOT found it ? if so, we must create it
-
 
224
   if (soundbuffer == NULL)
275
         if (soundbuffers == NULL)
225
   {
-
 
226
      // load the sound file
-
 
227
      Buffer_Initialize (&soundfile);
-
 
228
      if (!Buffer_ReadFromFileW (&soundfile, soundfile_path))
-
 
229
         return; // if unable to load this sound file, give up (FIXME: log something ?)
-
 
230
 
-
 
231
      // parse the WAV file
-
 
232
      sample_count = channel_count = sample_size = channel_size = 0;
-
 
233
      current_pos = 0;
-
 
234
      for (;;)
-
 
235
      {
-
 
236
         #define READ_DATA(type) *((type *) &soundfile.data[current_pos]); current_pos += sizeof (type); if (current_pos >= soundfile.size) break;
-
 
237
 
-
 
238
         chunk_id = READ_DATA (uint32_t);
-
 
239
         if (chunk_id == *((uint32_t *) "RIFF"))
-
 
240
         {
276
         {
241
            temp32 = READ_DATA (uint32_t); // skip the "chunk size" field
277
            soundbuffers = (openal_buffer_t *) SAFE_malloc (1, sizeof (openal_buffer_t), false); // allocate a new slot to initialize the linked list
242
            temp32 = READ_DATA (uint32_t); // skip the "riff style" field (typically "WAVE")
278
            soundbuffer = soundbuffers; // and set the pointer to the beginning of the list
243
         }
279
         }
244
         else if (chunk_id == *((uint32_t *) "fmt "))
280
         else
245
         {
281
         {
246
            blksiz = READ_DATA (uint32_t);
-
 
247
            temp16 = READ_DATA (uint16_t); if (temp16 != 1) break; // compressed WAVs are unsupported
282
            for (soundbuffer = soundbuffers; soundbuffer->next != NULL; soundbuffer = soundbuffer->next); // locate the last slot in the linked list
248
            temp32 = READ_DATA (uint16_t); channel_count = (int) temp16;
-
 
249
            temp32 = READ_DATA (uint32_t); sample_rate = (int) temp32;
-
 
250
            temp32 = READ_DATA (uint32_t);
-
 
251
            temp16 = READ_DATA (uint16_t); sample_size = (int) temp16;
-
 
252
            temp16 = READ_DATA (uint16_t); channel_size = (int) temp16 / 8;
283
            soundbuffer->next = (openal_buffer_t *) SAFE_malloc (1, sizeof (openal_buffer_t), false); // allocate a new slot and tie it there at the same time
253
            if (blksiz > 16)
-
 
254
               current_pos += blksiz - 16;
-
 
255
            if (current_pos >= soundfile.size)
-
 
256
               break; // don't go beyond the end of the file
284
            soundbuffer = soundbuffer->next; // and update the pointer to it
257
         }
285
         }
258
         else if (chunk_id == *((uint32_t *) "data"))
286
         soundbuffer->next = NULL; // this is the last sound buffer in the linked list, do remember it.
259
         {
287
 
260
            temp32 = READ_DATA (uint32_t); sample_count = (int) temp32;
288
         temp32 = wcslen (soundfile_path) + 1; // compute pathname buffer length (including null terminator)
261
            break; // current_pos is now at the beginning of data, and data measures sample_count bytes long
289
         soundbuffer->pathname = (wchar_t *) SAFE_malloc (temp32, sizeof (wchar_t), false); // allocate space for it
-
 
290
         wcscpy_s (soundbuffer->pathname, temp32, soundfile_path); // and copy this sound's pathname in the newly allocated buffer
262
         }
291
 
-
 
292
         // allocate the samples buffer and fill it, mixing all the WAV channels altogether in a 16-bit mono stream
-
 
293
         soundbuffer->openal_samples = (ALshort *) SAFE_malloc (sample_count, sizeof (ALshort), false);
263
         else
294
         for (sample_index = 0; sample_index < sample_count; sample_index++)
264
         {
295
         {
-
 
296
            sample_value = 0;
-
 
297
            if (channel_size == 1)
265
            blksiz = READ_DATA (uint32_t); // skip the "chunk size" field
298
               for (channel_index = 0; channel_index < channel_count; channel_index++)
-
 
299
                  sample_value += *((int8_t *) soundfile.data[current_pos + sample_index * sample_size + channel_index * channel_size]);
266
            current_pos += blksiz; // useless chunk, skip it
300
            else if (channel_size == 2)
-
 
301
               for (channel_index = 0; channel_index < channel_count; channel_index++)
-
 
302
                  sample_value += *((int16_t *) &soundfile.data[current_pos + sample_index * sample_size + channel_index * channel_size]);
267
            if (current_pos >= soundfile.size)
303
            sample_value /= channel_count;
268
               break; // don't go beyond the end of the file
304
            soundbuffer->openal_samples[sample_index] = (ALshort) sample_value;
269
         }
305
         }
270
 
306
 
-
 
307
         Buffer_Forget (&soundfile); // we can now forget this sound file
-
 
308
 
-
 
309
         alGenBuffers (1, &soundbuffer->openal_buffer); // create an OpenAL sound buffer and fill it with our samples
-
 
310
         alBufferData (soundbuffer->openal_buffer, AL_FORMAT_MONO16, soundbuffer->openal_samples, sample_count * sizeof (ALushort), (ALsizei) sample_rate);
271
         #undef READ_DATA
311
         if (alGetError () != AL_NO_ERROR)
-
 
312
            return; // FIXME: couldn't fill OpenAL buffer
272
      }
313
      }
273
      if ((sample_count == 0) || (channel_count == 0) || (sample_size == 0) || (channel_size == 0))
-
 
274
         return; // FIXME: not a wav file
-
 
275
 
314
 
276
      // compute the total number of samples (number of channels * number of frames)
-
 
277
      sample_count /= sample_size;
315
      // now we have a buffer to play
278
 
316
 
-
 
317
      // cycle through our known OpenAL sources and find a free one
-
 
318
      for (source_index = 0; source_index < source_count; source_index++)
-
 
319
         if (!sources[source_index].is_used)
-
 
320
            break; // break as soon as we find it
-
 
321
 
279
      // allocate space for one more sound buffer, and tie it to the linked list
322
      // have we NOT found any ? if so, reallocate so as to have one more
280
      if (soundbuffers == NULL)
323
      if (source_index == source_count)
281
      {
324
      {
282
         soundbuffers = (openal_buffer_t *) SAFE_malloc (1, sizeof (openal_buffer_t), false); // allocate a new slot to initialize the linked list
325
         sources = (openal_source_t *) SAFE_realloc (sources, source_count, source_count + 1, sizeof (openal_source_t), false);
283
         soundbuffer = soundbuffers; // and set the pointer to the beginning of the list
326
         source_count++; // one more source has been created
284
      }
327
      }
285
      else
-
 
286
      {
-
 
287
         for (soundbuffer = soundbuffers; soundbuffer->next != NULL; soundbuffer = soundbuffer->next); // locate the last slot in the linked list
-
 
288
         soundbuffer->next = (openal_buffer_t *) SAFE_malloc (1, sizeof (openal_buffer_t), false); // allocate a new slot and tie it there at the same time
-
 
289
         soundbuffer = soundbuffer->next; // and update the pointer to it
-
 
290
      }
-
 
291
      soundbuffer->next = NULL; // this is the last sound buffer in the linked list, do remember it.
-
 
292
 
328
 
293
      temp32 = wcslen (soundfile_path) + 1; // compute pathname buffer length (including null terminator)
329
      // now we have a source to play our buffer
294
      soundbuffer->pathname = (wchar_t *) SAFE_malloc (temp32, sizeof (wchar_t), false); // allocate space for it
-
 
295
      wcscpy_s (soundbuffer->pathname, temp32, soundfile_path); // and copy this sound's pathname in the newly allocated buffer
-
 
296
 
330
 
297
      // allocate the samples buffer and fill it, mixing all the WAV channels altogether in a 16-bit mono stream
-
 
298
      soundbuffer->openal_samples = (ALshort *) SAFE_malloc (sample_count, sizeof (ALshort), false);
-
 
299
      for (sample_index = 0; sample_index < sample_count; sample_index++)
331
      sources[source_index].is_used = true; // immediately mark it as used
300
      {
-
 
301
         sample_value = 0;
-
 
302
         if (channel_size == 1)
-
 
303
            for (channel_index = 0; channel_index < channel_count; channel_index++)
-
 
304
               sample_value += *((int8_t *) soundfile.data[current_pos + sample_index * sample_size + channel_index * channel_size]);
-
 
305
         else if (channel_size == 2)
-
 
306
            for (channel_index = 0; channel_index < channel_count; channel_index++)
-
 
307
               sample_value += *((int16_t *) &soundfile.data[current_pos + sample_index * sample_size + channel_index * channel_size]);
-
 
308
         sample_value /= channel_count;
-
 
309
         soundbuffer->openal_samples[sample_index] = (ALshort) sample_value;
332
      alGenSources (1, &sources[source_index].openal_source); // (re)create an OpenAL source
310
      }
-
 
311
 
333
 
-
 
334
      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)
312
      Buffer_Forget (&soundfile); // we can now forget this sound file
336
      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)
-
 
338
      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
313
 
340
 
314
      alGenBuffers (1, &soundbuffer->openal_buffer); // create an OpenAL sound buffer and fill it with our samples
341
      // play the source! Audio_Think() will dispose of it when it's finished
315
      alBufferData (soundbuffer->openal_buffer, AL_FORMAT_MONO16, soundbuffer->openal_samples, sample_count * sizeof (ALushort), (ALsizei) sample_rate);
-
 
316
      if (alGetError () != AL_NO_ERROR)
-
 
317
         return; // FIXME: couldn't fill OpenAL buffer
342
      alSourcePlay (sources[source_index].openal_source);
318
   }
343
   }
319
 
344
 
320
   // now we have a buffer to play
-
 
321
 
-
 
322
   // cycle through our known OpenAL sources and find a free one
345
   // cycle through all used sources and see if one is no longer playing
323
   for (source_index = 0; source_index < source_count; source_index++)
346
   for (source_index = 0; source_index < source_count; source_index++)
-
 
347
   {
324
      if (!sources[source_index].is_used)
348
      if (!sources[source_index].is_used)
325
         break; // break as soon as we find it
349
         continue; // skip unused slots
326
 
350
 
327
   // have we NOT found any ? if so, reallocate so as to have one more
351
      alGetSourcei (sources[source_index].openal_source, AL_SOURCE_STATE, &status); // get this source's playing state
328
   if (source_index == source_count)
352
      if (status == AL_PLAYING)
-
 
353
         continue; // skip sources that are still playing
329
   {
354
 
330
      sources = (openal_source_t *) SAFE_realloc (sources, source_count, source_count + 1, sizeof (openal_source_t), false);
355
      alSourcei (sources[source_index].openal_source, AL_BUFFER, NULL); // untie the buffer from this source
-
 
356
      alDeleteSources (1, &sources[source_index].openal_source); // and tell OpenAL to dispose of it
331
      source_count++; // one more source has been created
357
      sources[source_index].is_used = false; // mark this source as unused now
332
   }
358
   }
333
 
359
 
334
   // now we have a source to play our buffer
360
   return; // finished, audio has been handled
-
 
361
}
335
 
362
 
336
   sources[source_index].is_used = true; // immediately mark it as used
-
 
337
   alGenSources (1, &sources[source_index].openal_source); // (re)create an OpenAL source
-
 
338
 
363
 
339
   alSourcef (sources[source_index].openal_source, AL_PITCH, (ALfloat) pitch); // set the source's pitch
364
void Audio_PlaySound (int sound_type, float pos_x, float pos_y, float pos_z)
-
 
365
{
340
   alSourcef (sources[source_index].openal_source, AL_GAIN, 1.0f); // set the source's volume (full)
366
   // helper function to play a sound (WARNING: it is NOT thread-safe!)
341
   alSource3f (sources[source_index].openal_source, AL_POSITION, (ALfloat) pos_x * ATTENUATION_FACTOR, (ALfloat) pos_y * ATTENUATION_FACTOR, (ALfloat) pos_z * ATTENUATION_FACTOR);
-
 
-
 
367
 
342
   alSource3f (sources[source_index].openal_source, AL_VELOCITY, 0, 0, 0); // set the source's velocity (static)
368
   if (!options.want_sounds)
343
   alSourcei (sources[source_index].openal_source, AL_LOOPING, AL_FALSE); // set it as non-looping
369
      return; // if we want no sound, don't play anything
344
   alSourcei (sources[source_index].openal_source, AL_BUFFER, soundbuffer->openal_buffer); // attach our bufferized data to it
-
 
345
 
370
 
346
   // play the source! Audio_Think() will dispose of it when it's finished
371
   enqueued_sound.type = sound_type; // enqueue this sound for playing. Audio_Think() will take care of it.
347
   alSourcePlay (sources[source_index].openal_source);
372
   enqueued_sound.emitterlocation_x = pos_x;
-
 
373
   enqueued_sound.emitterlocation_y = pos_y;
-
 
374
   enqueued_sound.emitterlocation_z = pos_z;
348
 
375
 
349
   return; // finished
376
   return; // finished
350
}
377
}