2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 static portable_sampleframe_t paintbuffer[PAINTBUFFER_SIZE];
26 static portable_sampleframe_t paintbuffer_unswapped[PAINTBUFFER_SIZE];
28 extern speakerlayout_t snd_speakerlayout; // for querying the listeners
30 extern void SCR_CaptureVideo_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length);
31 static void S_CaptureAVISound(size_t length)
36 if (!cls.capturevideo.active)
39 // undo whatever swapping the channel layout (swapstereo, ALSA) did
40 for(j = 0; j < snd_speakerlayout.channels; ++j)
42 unsigned int j0 = snd_speakerlayout.listeners[j].channel_unswapped;
43 for(i = 0; i < length; ++i)
44 paintbuffer_unswapped[i].sample[j0] = paintbuffer[i].sample[j];
47 SCR_CaptureVideo_SoundFrame(paintbuffer_unswapped, length);
50 static void S_ConvertPaintBuffer(const portable_sampleframe_t *painted_ptr, void *rb_ptr, int nbframes, int width, int channels)
53 if (width == 2) // 16bit
55 short *snd_out = (short*)rb_ptr;
56 if (channels == 8) // 7.1 surround
58 for (i = 0;i < nbframes;i++, painted_ptr++)
60 *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
61 *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
62 *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
63 *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
64 *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
65 *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
66 *snd_out++ = bound(-32768, painted_ptr->sample[6], 32767);
67 *snd_out++ = bound(-32768, painted_ptr->sample[7], 32767);
70 else if (channels == 6) // 5.1 surround
72 for (i = 0; i < nbframes; i++, painted_ptr++)
74 *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
75 *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
76 *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
77 *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
78 *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
79 *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
82 else if (channels == 4) // 4.0 surround
84 for (i = 0; i < nbframes; i++, painted_ptr++)
86 *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
87 *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
88 *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
89 *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
92 else if (channels == 2) // 2.0 stereo
94 for (i = 0; i < nbframes; i++, painted_ptr++)
96 *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
97 *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
100 else if (channels == 1) // 1.0 mono
102 for (i = 0; i < nbframes; i++, painted_ptr++)
104 val = (painted_ptr->sample[0] + painted_ptr->sample[1]) >> 1;
105 *snd_out++ = bound(-32768, val, 32767);
109 // noise is really really annoying
111 memset(rb_ptr, 0, nbframes * channels * width);
115 unsigned char *snd_out = (unsigned char*)rb_ptr;
116 if (channels == 8) // 7.1 surround
118 for (i = 0; i < nbframes; i++, painted_ptr++)
120 val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
121 val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
122 val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
123 val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
124 val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
125 val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
126 val = (painted_ptr->sample[6] >> 8) + 128; *snd_out++ = bound(0, val, 255);
127 val = (painted_ptr->sample[7] >> 8) + 128; *snd_out++ = bound(0, val, 255);
130 else if (channels == 6) // 5.1 surround
132 for (i = 0; i < nbframes; i++, painted_ptr++)
134 val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
135 val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
136 val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
137 val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
138 val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
139 val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
142 else if (channels == 4) // 4.0 surround
144 for (i = 0; i < nbframes; i++, painted_ptr++)
146 val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
147 val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
148 val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
149 val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
152 else if (channels == 2) // 2.0 stereo
154 for (i = 0; i < nbframes; i++, painted_ptr++)
156 val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
157 val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
160 else if (channels == 1) // 1.0 mono
162 for (i = 0;i < nbframes;i++, painted_ptr++)
164 val = ((painted_ptr->sample[0] + painted_ptr->sample[1]) >> 9) + 128;
165 *snd_out++ = bound(0, val, 255);
169 // noise is really really annoying
171 memset(rb_ptr, 128, nbframes * channels);
177 ===============================================================================
181 ===============================================================================
184 static qboolean SND_PaintChannel (channel_t *ch, portable_sampleframe_t *paint, unsigned int count)
186 int vol[SND_LISTENERS];
187 const snd_buffer_t *sb;
188 unsigned int i, sb_offset;
190 // move to the stack (do we need to?)
191 for (i = 0;i < SND_LISTENERS;i++)
192 vol[i] = ch->listener_volume[i];
194 // if volumes are all zero, just return
195 for (i = 0;i < SND_LISTENERS;i++)
198 if (i == SND_LISTENERS)
202 sb = ch->sfx->fetcher->getsb (ch->sfx->fetcher_data, &ch->fetcher_data, &sb_offset, count);
205 Con_DPrintf("SND_PaintChannel: ERROR: can't get sound buffer from sfx \"%s\"\n",
206 ch->sfx->name); // , count); // or add this? FIXME
211 #if SND_LISTENERS != 8
212 # error the following code only supports up to 8 channels, update it
214 if (sb->format.width == 1)
216 const signed char *samples = (signed char*)sb->samples + (ch->pos - sb_offset) * sb->format.channels;
218 // Stereo sound support
219 if (sb->format.channels == 2)
221 if (vol[6] + vol[7] > 0)
223 for (i = 0;i < count;i++)
225 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
226 paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
227 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
228 paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
229 paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 9;
230 paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 9;
231 paint[i].sample[6] += (samples[0] * vol[6]) >> 8;
232 paint[i].sample[7] += (samples[1] * vol[7]) >> 8;
236 else if (vol[4] + vol[5] > 0)
238 for (i = 0;i < count;i++)
240 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
241 paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
242 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
243 paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
244 paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 9;
245 paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 9;
249 else if (vol[2] + vol[3] > 0)
251 for (i = 0;i < count;i++)
253 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
254 paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
255 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
256 paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
260 else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
262 for (i = 0;i < count;i++)
264 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
265 paint[i].sample[1] -= (samples[1] * vol[1]) >> 8;
269 else if (vol[0] + vol[1] > 0)
271 for (i = 0;i < count;i++)
273 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
274 paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
279 else if (sb->format.channels == 1)
281 if (vol[6] + vol[7] > 0)
283 for (i = 0;i < count;i++)
285 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
286 paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
287 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
288 paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
289 paint[i].sample[4] += (samples[0] * vol[4]) >> 8;
290 paint[i].sample[5] += (samples[0] * vol[5]) >> 8;
291 paint[i].sample[6] += (samples[0] * vol[6]) >> 8;
292 paint[i].sample[7] += (samples[0] * vol[7]) >> 8;
296 else if (vol[4] + vol[5] > 0)
298 for (i = 0;i < count;i++)
300 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
301 paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
302 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
303 paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
304 paint[i].sample[4] += (samples[0] * vol[4]) >> 8;
305 paint[i].sample[5] += (samples[0] * vol[5]) >> 8;
309 else if (vol[2] + vol[3] > 0)
311 for (i = 0;i < count;i++)
313 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
314 paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
315 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
316 paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
320 else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
322 for (i = 0;i < count;i++)
324 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
325 paint[i].sample[1] -= (samples[0] * vol[1]) >> 8;
329 else if (vol[0] + vol[1] > 0)
331 for (i = 0;i < count;i++)
333 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
334 paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
340 return false; // unsupported number of channels in sound
342 else if (sb->format.width == 2)
344 const signed short *samples = (signed short*)sb->samples + (ch->pos - sb_offset) * sb->format.channels;
346 // Stereo sound support
347 if (sb->format.channels == 2)
349 if (vol[6] + vol[7] > 0)
351 for (i = 0;i < count;i++)
353 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
354 paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
355 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
356 paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
357 paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 17;
358 paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 17;
359 paint[i].sample[6] += (samples[0] * vol[6]) >> 16;
360 paint[i].sample[7] += (samples[1] * vol[7]) >> 16;
364 else if (vol[4] + vol[5] > 0)
366 for (i = 0;i < count;i++)
368 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
369 paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
370 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
371 paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
372 paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 17;
373 paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 17;
377 else if (vol[2] + vol[3] > 0)
379 for (i = 0;i < count;i++)
381 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
382 paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
383 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
384 paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
388 else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
390 for (i = 0;i < count;i++)
392 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
393 paint[i].sample[1] -= (samples[1] * vol[1]) >> 16;
397 else if (vol[0] + vol[1] > 0)
399 for (i = 0;i < count;i++)
401 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
402 paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
407 else if (sb->format.channels == 1)
409 if (vol[6] + vol[7] > 0)
411 for (i = 0;i < count;i++)
413 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
414 paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
415 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
416 paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
417 paint[i].sample[4] += (samples[0] * vol[4]) >> 16;
418 paint[i].sample[5] += (samples[0] * vol[5]) >> 16;
419 paint[i].sample[6] += (samples[0] * vol[6]) >> 16;
420 paint[i].sample[7] += (samples[0] * vol[7]) >> 16;
424 else if (vol[4] + vol[5] > 0)
426 for (i = 0;i < count;i++)
428 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
429 paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
430 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
431 paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
432 paint[i].sample[4] += (samples[0] * vol[4]) >> 16;
433 paint[i].sample[5] += (samples[0] * vol[5]) >> 16;
437 else if (vol[2] + vol[3] > 0)
439 for (i = 0;i < count;i++)
441 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
442 paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
443 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
444 paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
448 else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
450 for (i = 0;i < count;i++)
452 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
453 paint[i].sample[1] -= (samples[0] * vol[1]) >> 16;
457 else if (vol[0] + vol[1] > 0)
459 for (i = 0;i < count;i++)
461 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
462 paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
468 return false; // unsupported number of channels in sound
474 void S_MixToBuffer(void *stream, unsigned int bufferframes)
479 unsigned char *outbytes = (unsigned char *) stream;
481 // mix as many times as needed to fill the requested buffer
484 // limit to the size of the paint buffer
485 frames = min(bufferframes, PAINTBUFFER_SIZE);
487 // clear the paint buffer
488 memset (paintbuffer, 0, frames * sizeof (paintbuffer[0]));
490 // paint in the channels.
491 // channels with zero volumes still advance in time but don't paint.
493 for (i = 0; i < total_channels ; i++, ch++)
502 if (!S_LoadSound (sfx, true))
504 if (ch->flags & CHANNELFLAG_PAUSED)
511 count = min(count, (int)frames - ltime);
516 while (ltime < (int)frames)
518 // paint up to end of buffer or of input, whichever is lower
519 count = sfx->total_length - ch->pos;
520 count = bound(0, count, (int)frames - ltime);
523 SND_PaintChannel (ch, paintbuffer + ltime, count);
528 // if at end of sfx, loop or stop the channel
529 if (ch->pos >= (int)sfx->total_length)
531 if (sfx->loopstart < sfx->total_length)
532 ch->pos = sfx->loopstart;
533 else if (ch->flags & CHANNELFLAG_FORCELOOP)
537 S_StopChannel (ch - channels, false);
544 if (!snd_usethreadedmixing)
545 S_CaptureAVISound(frames);
547 S_ConvertPaintBuffer(paintbuffer, outbytes, frames, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
549 // advance the output pointer
550 outbytes += frames * snd_renderbuffer->format.width * snd_renderbuffer->format.channels;
551 bufferframes -= frames;