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;
191 sfx = ch->sfx; // fetch the volatile variable
192 if (!sfx) // given that this is called by the mixer thread, this never happens, but...
195 // move to the stack (do we need to?)
196 for (i = 0;i < SND_LISTENERS;i++)
197 vol[i] = ch->listener_volume[i];
199 // if volumes are all zero, just return
200 for (i = 0;i < SND_LISTENERS;i++)
203 if (i == SND_LISTENERS)
207 sb = sfx->fetcher->getsb (sfx->fetcher_data, &ch->fetcher_data, &sb_offset, count);
210 Con_DPrintf("SND_PaintChannel: ERROR: can't get sound buffer from sfx \"%s\"\n",
211 sfx->name); // , count); // or add this? FIXME
216 #if SND_LISTENERS != 8
217 # error the following code only supports up to 8 channels, update it
219 if (sb->format.width == 1)
221 const signed char *samples = (signed char*)sb->samples + (ch->pos - sb_offset) * sb->format.channels;
223 // Stereo sound support
224 if (sb->format.channels == 2)
226 if (vol[6] + vol[7] > 0)
228 for (i = 0;i < count;i++)
230 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
231 paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
232 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
233 paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
234 paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 9;
235 paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 9;
236 paint[i].sample[6] += (samples[0] * vol[6]) >> 8;
237 paint[i].sample[7] += (samples[1] * vol[7]) >> 8;
241 else if (vol[4] + vol[5] > 0)
243 for (i = 0;i < count;i++)
245 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
246 paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
247 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
248 paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
249 paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 9;
250 paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 9;
254 else if (vol[2] + vol[3] > 0)
256 for (i = 0;i < count;i++)
258 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
259 paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
260 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
261 paint[i].sample[3] += (samples[1] * vol[3]) >> 8;
265 else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
267 for (i = 0;i < count;i++)
269 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
270 paint[i].sample[1] -= (samples[1] * vol[1]) >> 8;
274 else if (vol[0] + vol[1] > 0)
276 for (i = 0;i < count;i++)
278 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
279 paint[i].sample[1] += (samples[1] * vol[1]) >> 8;
284 else if (sb->format.channels == 1)
286 if (vol[6] + vol[7] > 0)
288 for (i = 0;i < count;i++)
290 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
291 paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
292 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
293 paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
294 paint[i].sample[4] += (samples[0] * vol[4]) >> 8;
295 paint[i].sample[5] += (samples[0] * vol[5]) >> 8;
296 paint[i].sample[6] += (samples[0] * vol[6]) >> 8;
297 paint[i].sample[7] += (samples[0] * vol[7]) >> 8;
301 else if (vol[4] + vol[5] > 0)
303 for (i = 0;i < count;i++)
305 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
306 paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
307 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
308 paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
309 paint[i].sample[4] += (samples[0] * vol[4]) >> 8;
310 paint[i].sample[5] += (samples[0] * vol[5]) >> 8;
314 else if (vol[2] + vol[3] > 0)
316 for (i = 0;i < count;i++)
318 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
319 paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
320 paint[i].sample[2] += (samples[0] * vol[2]) >> 8;
321 paint[i].sample[3] += (samples[0] * vol[3]) >> 8;
325 else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
327 for (i = 0;i < count;i++)
329 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
330 paint[i].sample[1] -= (samples[0] * vol[1]) >> 8;
334 else if (vol[0] + vol[1] > 0)
336 for (i = 0;i < count;i++)
338 paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
339 paint[i].sample[1] += (samples[0] * vol[1]) >> 8;
345 return false; // unsupported number of channels in sound
347 else if (sb->format.width == 2)
349 const signed short *samples = (signed short*)sb->samples + (ch->pos - sb_offset) * sb->format.channels;
351 // Stereo sound support
352 if (sb->format.channels == 2)
354 if (vol[6] + vol[7] > 0)
356 for (i = 0;i < count;i++)
358 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
359 paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
360 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
361 paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
362 paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 17;
363 paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 17;
364 paint[i].sample[6] += (samples[0] * vol[6]) >> 16;
365 paint[i].sample[7] += (samples[1] * vol[7]) >> 16;
369 else if (vol[4] + vol[5] > 0)
371 for (i = 0;i < count;i++)
373 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
374 paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
375 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
376 paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
377 paint[i].sample[4] += ((samples[0] + samples[1]) * vol[4]) >> 17;
378 paint[i].sample[5] += ((samples[0] + samples[1]) * vol[5]) >> 17;
382 else if (vol[2] + vol[3] > 0)
384 for (i = 0;i < count;i++)
386 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
387 paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
388 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
389 paint[i].sample[3] += (samples[1] * vol[3]) >> 16;
393 else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
395 for (i = 0;i < count;i++)
397 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
398 paint[i].sample[1] -= (samples[1] * vol[1]) >> 16;
402 else if (vol[0] + vol[1] > 0)
404 for (i = 0;i < count;i++)
406 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
407 paint[i].sample[1] += (samples[1] * vol[1]) >> 16;
412 else if (sb->format.channels == 1)
414 if (vol[6] + vol[7] > 0)
416 for (i = 0;i < count;i++)
418 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
419 paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
420 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
421 paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
422 paint[i].sample[4] += (samples[0] * vol[4]) >> 16;
423 paint[i].sample[5] += (samples[0] * vol[5]) >> 16;
424 paint[i].sample[6] += (samples[0] * vol[6]) >> 16;
425 paint[i].sample[7] += (samples[0] * vol[7]) >> 16;
429 else if (vol[4] + vol[5] > 0)
431 for (i = 0;i < count;i++)
433 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
434 paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
435 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
436 paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
437 paint[i].sample[4] += (samples[0] * vol[4]) >> 16;
438 paint[i].sample[5] += (samples[0] * vol[5]) >> 16;
442 else if (vol[2] + vol[3] > 0)
444 for (i = 0;i < count;i++)
446 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
447 paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
448 paint[i].sample[2] += (samples[0] * vol[2]) >> 16;
449 paint[i].sample[3] += (samples[0] * vol[3]) >> 16;
453 else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
455 for (i = 0;i < count;i++)
457 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
458 paint[i].sample[1] -= (samples[0] * vol[1]) >> 16;
462 else if (vol[0] + vol[1] > 0)
464 for (i = 0;i < count;i++)
466 paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
467 paint[i].sample[1] += (samples[0] * vol[1]) >> 16;
473 return false; // unsupported number of channels in sound
479 void S_MixToBuffer(void *stream, unsigned int bufferframes)
484 unsigned char *outbytes = (unsigned char *) stream;
486 // mix as many times as needed to fill the requested buffer
489 // limit to the size of the paint buffer
490 frames = min(bufferframes, PAINTBUFFER_SIZE);
492 // clear the paint buffer
493 memset (paintbuffer, 0, frames * sizeof (paintbuffer[0]));
495 // paint in the channels.
496 // channels with zero volumes still advance in time but don't paint.
498 for (i = 0; i < total_channels ; i++, ch++)
507 if (!S_LoadSound (sfx, true))
509 if (ch->flags & CHANNELFLAG_PAUSED)
511 if (!sfx->total_length)
513 if (sfx->total_length > 1<<30)
514 Sys_Error("S_MixToBuffer: sfx corrupt\n");
520 count = min(count, (int)frames - ltime);
525 while (ltime < (int)frames)
527 // paint up to end of buffer or of input, whichever is lower
528 count = sfx->total_length - ch->pos;
529 count = bound(0, count, (int)frames - ltime);
530 // mix the remaining samples
533 SND_PaintChannel (ch, paintbuffer + ltime, count);
537 // if at end of sfx, loop or stop the channel
540 if (sfx->loopstart < sfx->total_length)
541 ch->pos = sfx->loopstart;
542 else if (ch->flags & CHANNELFLAG_FORCELOOP)
546 S_StopChannel (ch - channels, false, false);
553 if (!snd_usethreadedmixing)
554 S_CaptureAVISound(frames);
556 S_ConvertPaintBuffer(paintbuffer, outbytes, frames, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
558 // advance the output pointer
559 outbytes += frames * snd_renderbuffer->format.width * snd_renderbuffer->format.channels;
560 bufferframes -= frames;