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.
24 extern cvar_t snd_softclip;
26 static portable_sampleframe_t paintbuffer[PAINTBUFFER_SIZE];
27 static portable_sampleframe_t paintbuffer_unswapped[PAINTBUFFER_SIZE];
29 extern speakerlayout_t snd_speakerlayout; // for querying the listeners
31 #ifdef CONFIG_VIDEO_CAPTURE
32 static void S_CaptureAVISound(const portable_sampleframe_t *sampleframes, size_t length)
37 if (!cls.capturevideo.active)
40 // undo whatever swapping the channel layout (swapstereo, ALSA) did
41 for(j = 0; j < snd_speakerlayout.channels; ++j)
43 unsigned int j0 = snd_speakerlayout.listeners[j].channel_unswapped;
44 for(i = 0; i < length; ++i)
45 paintbuffer_unswapped[i].sample[j0] = sampleframes[i].sample[j];
48 SCR_CaptureVideo_SoundFrame(paintbuffer_unswapped, length);
52 extern cvar_t snd_softclip;
54 static void S_SoftClipPaintBuffer(portable_sampleframe_t *painted_ptr, int nbframes, int width, int nchannels)
58 if((snd_softclip.integer == 1 && width <= 2) || snd_softclip.integer > 1)
60 portable_sampleframe_t *p = painted_ptr;
63 /* Soft clipping, the sound of a dream, thanks to Jon Wattes
64 post to Musicdsp.org */
65 #define SOFTCLIP(x) (x) = sin(bound(-M_PI/2, (x), M_PI/2)) * 0.25
68 // let's do a simple limiter instead, seems to sound better
69 static float maxvol = 0;
70 maxvol = max(1.0f, maxvol * (1.0f - nbframes / (0.4f * snd_renderbuffer->format.speed)));
71 #define SOFTCLIP(x) if(fabs(x)>maxvol) maxvol=fabs(x); (x) /= maxvol;
73 if (nchannels == 8) // 7.1 surround
75 for (i = 0;i < nbframes;i++, p++)
77 SOFTCLIP(p->sample[0]);
78 SOFTCLIP(p->sample[1]);
79 SOFTCLIP(p->sample[2]);
80 SOFTCLIP(p->sample[3]);
81 SOFTCLIP(p->sample[4]);
82 SOFTCLIP(p->sample[5]);
83 SOFTCLIP(p->sample[6]);
84 SOFTCLIP(p->sample[7]);
87 else if (nchannels == 6) // 5.1 surround
89 for (i = 0; i < nbframes; i++, p++)
91 SOFTCLIP(p->sample[0]);
92 SOFTCLIP(p->sample[1]);
93 SOFTCLIP(p->sample[2]);
94 SOFTCLIP(p->sample[3]);
95 SOFTCLIP(p->sample[4]);
96 SOFTCLIP(p->sample[5]);
99 else if (nchannels == 4) // 4.0 surround
101 for (i = 0; i < nbframes; i++, p++)
103 SOFTCLIP(p->sample[0]);
104 SOFTCLIP(p->sample[1]);
105 SOFTCLIP(p->sample[2]);
106 SOFTCLIP(p->sample[3]);
109 else if (nchannels == 2) // 2.0 stereo
111 for (i = 0; i < nbframes; i++, p++)
113 SOFTCLIP(p->sample[0]);
114 SOFTCLIP(p->sample[1]);
117 else if (nchannels == 1) // 1.0 mono
119 for (i = 0; i < nbframes; i++, p++)
121 SOFTCLIP(p->sample[0]);
128 static void S_ConvertPaintBuffer(portable_sampleframe_t *painted_ptr, void *rb_ptr, int nbframes, int width, int nchannels)
131 if (width == 4) // 32bit float
133 float *snd_out = (float*)rb_ptr;
134 if (nchannels == 8) // 7.1 surround
136 for (i = 0; i < nbframes; i++, painted_ptr++)
138 *snd_out++ = painted_ptr->sample[0];
139 *snd_out++ = painted_ptr->sample[1];
140 *snd_out++ = painted_ptr->sample[2];
141 *snd_out++ = painted_ptr->sample[3];
142 *snd_out++ = painted_ptr->sample[4];
143 *snd_out++ = painted_ptr->sample[5];
144 *snd_out++ = painted_ptr->sample[6];
145 *snd_out++ = painted_ptr->sample[7];
148 else if (nchannels == 6) // 5.1 surround
150 for (i = 0; i < nbframes; i++, painted_ptr++)
152 *snd_out++ = painted_ptr->sample[0];
153 *snd_out++ = painted_ptr->sample[1];
154 *snd_out++ = painted_ptr->sample[2];
155 *snd_out++ = painted_ptr->sample[3];
156 *snd_out++ = painted_ptr->sample[4];
157 *snd_out++ = painted_ptr->sample[5];
160 else if (nchannels == 4) // 4.0 surround
162 for (i = 0; i < nbframes; i++, painted_ptr++)
164 *snd_out++ = painted_ptr->sample[0];
165 *snd_out++ = painted_ptr->sample[1];
166 *snd_out++ = painted_ptr->sample[2];
167 *snd_out++ = painted_ptr->sample[3];
170 else if (nchannels == 2) // 2.0 stereo
172 for (i = 0; i < nbframes; i++, painted_ptr++)
174 *snd_out++ = painted_ptr->sample[0];
175 *snd_out++ = painted_ptr->sample[1];
178 else if (nchannels == 1) // 1.0 mono
180 for (i = 0; i < nbframes; i++, painted_ptr++)
182 *snd_out++ = painted_ptr->sample[0];
186 // noise is really really annoying
188 memset(rb_ptr, 0, nbframes * nchannels * width);
190 else if (width == 2) // 16bit
192 short *snd_out = (short*)rb_ptr;
193 if (nchannels == 8) // 7.1 surround
195 for (i = 0;i < nbframes;i++, painted_ptr++)
197 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
198 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
199 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
200 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
201 val = (int)(painted_ptr->sample[4] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
202 val = (int)(painted_ptr->sample[5] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
203 val = (int)(painted_ptr->sample[6] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
204 val = (int)(painted_ptr->sample[7] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
207 else if (nchannels == 6) // 5.1 surround
209 for (i = 0; i < nbframes; i++, painted_ptr++)
211 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
212 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
213 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
214 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
215 val = (int)(painted_ptr->sample[4] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
216 val = (int)(painted_ptr->sample[5] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
219 else if (nchannels == 4) // 4.0 surround
221 for (i = 0; i < nbframes; i++, painted_ptr++)
223 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
224 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
225 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
226 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
229 else if (nchannels == 2) // 2.0 stereo
231 for (i = 0; i < nbframes; i++, painted_ptr++)
233 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
234 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
237 else if (nchannels == 1) // 1.0 mono
239 for (i = 0; i < nbframes; i++, painted_ptr++)
241 val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 16384.0f);*snd_out++ = bound(-32768, val, 32767);
245 // noise is really really annoying
247 memset(rb_ptr, 0, nbframes * nchannels * width);
251 unsigned char *snd_out = (unsigned char*)rb_ptr;
252 if (nchannels == 8) // 7.1 surround
254 for (i = 0; i < nbframes; i++, painted_ptr++)
256 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
257 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
258 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
259 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
260 val = (int)(painted_ptr->sample[4] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
261 val = (int)(painted_ptr->sample[5] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
262 val = (int)(painted_ptr->sample[6] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
263 val = (int)(painted_ptr->sample[7] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
266 else if (nchannels == 6) // 5.1 surround
268 for (i = 0; i < nbframes; i++, painted_ptr++)
270 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
271 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
272 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
273 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
274 val = (int)(painted_ptr->sample[4] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
275 val = (int)(painted_ptr->sample[5] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
278 else if (nchannels == 4) // 4.0 surround
280 for (i = 0; i < nbframes; i++, painted_ptr++)
282 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
283 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
284 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
285 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
288 else if (nchannels == 2) // 2.0 stereo
290 for (i = 0; i < nbframes; i++, painted_ptr++)
292 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
293 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
296 else if (nchannels == 1) // 1.0 mono
298 for (i = 0;i < nbframes;i++, painted_ptr++)
300 val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 64.0f) + 128; *snd_out++ = bound(0, val, 255);
304 // noise is really really annoying
306 memset(rb_ptr, 128, nbframes * nchannels);
312 ===============================================================================
316 ===============================================================================
319 void S_MixToBuffer(void *stream, unsigned int bufferframes)
324 unsigned char *outbytes = (unsigned char *) stream;
326 portable_sampleframe_t *paint;
339 #define S_FETCHBUFFERSIZE 4096
340 float fetchsampleframes[S_FETCHBUFFERSIZE*2];
341 const float *fetchsampleframe;
342 float vol[SND_LISTENERS];
351 // mix as many times as needed to fill the requested buffer
354 // limit to the size of the paint buffer
355 totalmixframes = min(bufferframes, PAINTBUFFER_SIZE);
357 // clear the paint buffer
358 memset(paintbuffer, 0, totalmixframes * sizeof(paintbuffer[0]));
360 // paint in the channels.
361 // channels with zero volumes still advance in time but don't paint.
362 ch = channels; // cppcheck complains here but it is wrong, channels is a channel_t[MAX_CHANNELS] and not an int
363 for (channelindex = 0;channelindex < (int)total_channels;channelindex++, ch++)
368 if (!S_LoadSound (sfx, true))
370 if (ch->flags & CHANNELFLAG_PAUSED)
372 if (!sfx->total_length)
375 // copy the channel information to the stack for reference, otherwise the
376 // values might change during a mix if the spatializer is updating them
377 // (note: this still may get some old and some new values!)
379 speedd = ch->mixspeed * sfx->format.speed / snd_renderbuffer->format.speed;
380 for (i = 0;i < SND_LISTENERS;i++)
381 vol[i] = ch->volume[i];
383 // check total volume level, because we can skip some code on silent sounds but other code must still run (position updates mainly)
385 for (i = 0;i < SND_LISTENERS;i++)
388 switch(snd_renderbuffer->format.width)
391 silent = maxvol < (1.0f / (256.0f));
392 // so silent it has zero effect
395 silent = maxvol < (1.0f / (65536.0f));
396 // so silent it has zero effect
398 default: // floating point
399 silent = maxvol < 1.0e-13f;
400 // 130 dB is difference between hearing
401 // threshold and a jackhammer from
403 // therefore, anyone who turns up
404 // volume so much they notice this
405 // cutoff, likely already has their
406 // ear-drums blown out anyway.
410 // when doing prologic mixing, some channels invert one side
411 if (ch->prologic_invert == -1)
414 // get some sfx info in a consistent form
415 totallength = sfx->total_length;
416 loopstart = (int)sfx->loopstart < totallength ? (int)sfx->loopstart : ((ch->flags & CHANNELFLAG_FORCELOOP) ? 0 : totallength);
417 looping = loopstart < totallength;
419 // do the actual paint now (may skip work if silent)
422 for (wantframes = totalmixframes;wantframes > 0;posd += count * speedd, wantframes -= count)
424 // check if this is a delayed sound
427 // for a delayed sound we have to eat into the delay first
428 count = (int)floor(-posd / speedd) + 1;
429 count = bound(1, count, wantframes);
430 // let the for loop iterator apply the skip
434 // compute a fetch size that won't overflow our buffer
438 istartframe = (int)floor(posd);
439 iendframe = (int)floor(posd + (count-1) * speedd);
440 ilengthframes = count > 1 ? (iendframe - istartframe + 2) : 2;
441 if (ilengthframes <= S_FETCHBUFFERSIZE)
443 // reduce count by 25% and try again
447 // zero whole fetch buffer for safety
448 // (floating point noise from uninitialized memory = HORRIBLE)
449 // otherwise we would only need to clear the excess
451 memset(fetchsampleframes, 0, ilengthframes*sfx->format.channels*sizeof(fetchsampleframes[0]));
453 // if looping, do multiple fetches
457 fetch = min(ilengthframes - fetched, totallength - istartframe);
461 sfx->fetcher->getsamplesfloat(ch, sfx, istartframe, fetch, fetchsampleframes + fetched*sfx->format.channels);
462 istartframe += fetch;
465 if (istartframe == totallength && looping && fetched < ilengthframes)
467 // loop and fetch some more
468 posd += loopstart - totallength;
469 istartframe = loopstart;
477 // set up our fixedpoint resampling variables (float to int conversions are expensive so do not do one per sampleframe)
478 fetchsampleframe = fetchsampleframes;
479 indexfrac = (int)floor((posd - floor(posd)) * 65536.0);
480 indexfracstep = (int)floor(speedd * 65536.0);
483 if (sfx->format.channels == 2)
486 #if SND_LISTENERS != 8
487 #error the following code only supports up to 8 channels, update it
489 if (snd_speakerlayout.channels > 2)
492 for (i = 0;i < count;i++, paint++)
494 lerp[1] = indexfrac * (1.0f / 65536.0f);
495 lerp[0] = 1.0f - lerp[1];
496 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
497 sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
498 sample[2] = (sample[0] + sample[1]) * 0.5f;
499 paint->sample[0] += sample[0] * vol[0];
500 paint->sample[1] += sample[1] * vol[1];
501 paint->sample[2] += sample[0] * vol[2];
502 paint->sample[3] += sample[1] * vol[3];
503 paint->sample[4] += sample[2] * vol[4];
504 paint->sample[5] += sample[2] * vol[5];
505 paint->sample[6] += sample[0] * vol[6];
506 paint->sample[7] += sample[1] * vol[7];
507 indexfrac += indexfracstep;
508 fetchsampleframe += 2 * (indexfrac >> 16);
515 for (i = 0;i < count;i++, paint++)
517 lerp[1] = indexfrac * (1.0f / 65536.0f);
518 lerp[0] = 1.0f - lerp[1];
519 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
520 sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
521 paint->sample[0] += sample[0] * vol[0];
522 paint->sample[1] += sample[1] * vol[1];
523 indexfrac += indexfracstep;
524 fetchsampleframe += 2 * (indexfrac >> 16);
529 else if (sfx->format.channels == 1)
531 // most sounds are mono
532 #if SND_LISTENERS != 8
533 #error the following code only supports up to 8 channels, update it
535 if (snd_speakerlayout.channels > 2)
538 for (i = 0;i < count;i++, paint++)
540 lerp[1] = indexfrac * (1.0f / 65536.0f);
541 lerp[0] = 1.0f - lerp[1];
542 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
543 paint->sample[0] += sample[0] * vol[0];
544 paint->sample[1] += sample[0] * vol[1];
545 paint->sample[2] += sample[0] * vol[2];
546 paint->sample[3] += sample[0] * vol[3];
547 paint->sample[4] += sample[0] * vol[4];
548 paint->sample[5] += sample[0] * vol[5];
549 paint->sample[6] += sample[0] * vol[6];
550 paint->sample[7] += sample[0] * vol[7];
551 indexfrac += indexfracstep;
552 fetchsampleframe += (indexfrac >> 16);
559 for (i = 0;i < count;i++, paint++)
561 lerp[1] = indexfrac * (1.0f / 65536.0f);
562 lerp[0] = 1.0f - lerp[1];
563 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
564 paint->sample[0] += sample[0] * vol[0];
565 paint->sample[1] += sample[0] * vol[1];
566 indexfrac += indexfracstep;
567 fetchsampleframe += (indexfrac >> 16);
575 if (!looping && istartframe == totallength)
576 S_StopChannel(ch - channels, false, false);
579 S_SoftClipPaintBuffer(paintbuffer, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
581 #ifdef CONFIG_VIDEO_CAPTURE
582 if (!snd_usethreadedmixing)
583 S_CaptureAVISound(paintbuffer, totalmixframes);
586 S_ConvertPaintBuffer(paintbuffer, outbytes, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
588 // advance the output pointer
589 outbytes += totalmixframes * snd_renderbuffer->format.width * snd_renderbuffer->format.channels;
590 bufferframes -= totalmixframes;