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 *paintbuffer, 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] = paintbuffer[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 channels)
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 (channels == 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 (channels == 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 (channels == 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 (channels == 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 (channels == 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 channels)
132 // FIXME: add 24bit and 32bit float formats
133 // FIXME: optimize with SSE intrinsics?
134 if (width == 2) // 16bit
136 short *snd_out = (short*)rb_ptr;
137 if (channels == 8) // 7.1 surround
139 for (i = 0;i < nbframes;i++, painted_ptr++)
141 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
142 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
143 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
144 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
145 val = (int)(painted_ptr->sample[4] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
146 val = (int)(painted_ptr->sample[5] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
147 val = (int)(painted_ptr->sample[6] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
148 val = (int)(painted_ptr->sample[7] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
151 else if (channels == 6) // 5.1 surround
153 for (i = 0; i < nbframes; i++, painted_ptr++)
155 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
156 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
157 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
158 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
159 val = (int)(painted_ptr->sample[4] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
160 val = (int)(painted_ptr->sample[5] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
163 else if (channels == 4) // 4.0 surround
165 for (i = 0; i < nbframes; i++, painted_ptr++)
167 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
168 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
169 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
170 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
173 else if (channels == 2) // 2.0 stereo
175 for (i = 0; i < nbframes; i++, painted_ptr++)
177 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
178 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
181 else if (channels == 1) // 1.0 mono
183 for (i = 0; i < nbframes; i++, painted_ptr++)
185 val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 16384.0f);*snd_out++ = bound(-32768, val, 32767);
189 // noise is really really annoying
191 memset(rb_ptr, 0, nbframes * channels * width);
195 unsigned char *snd_out = (unsigned char*)rb_ptr;
196 if (channels == 8) // 7.1 surround
198 for (i = 0; i < nbframes; i++, painted_ptr++)
200 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
201 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
202 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
203 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
204 val = (int)(painted_ptr->sample[4] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
205 val = (int)(painted_ptr->sample[5] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
206 val = (int)(painted_ptr->sample[6] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
207 val = (int)(painted_ptr->sample[7] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
210 else if (channels == 6) // 5.1 surround
212 for (i = 0; i < nbframes; i++, painted_ptr++)
214 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
215 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
216 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
217 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
218 val = (int)(painted_ptr->sample[4] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
219 val = (int)(painted_ptr->sample[5] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
222 else if (channels == 4) // 4.0 surround
224 for (i = 0; i < nbframes; i++, painted_ptr++)
226 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
227 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
228 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
229 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
232 else if (channels == 2) // 2.0 stereo
234 for (i = 0; i < nbframes; i++, painted_ptr++)
236 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
237 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
240 else if (channels == 1) // 1.0 mono
242 for (i = 0;i < nbframes;i++, painted_ptr++)
244 val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 64.0f) + 128; *snd_out++ = bound(0, val, 255);
248 // noise is really really annoying
250 memset(rb_ptr, 128, nbframes * channels);
256 ===============================================================================
260 ===============================================================================
263 void S_MixToBuffer(void *stream, unsigned int bufferframes)
268 unsigned char *outbytes = (unsigned char *) stream;
270 portable_sampleframe_t *paint;
283 #define S_FETCHBUFFERSIZE 4096
284 float fetchsampleframes[S_FETCHBUFFERSIZE*2];
285 const float *fetchsampleframe;
286 float vol[SND_LISTENERS];
295 // mix as many times as needed to fill the requested buffer
298 // limit to the size of the paint buffer
299 totalmixframes = min(bufferframes, PAINTBUFFER_SIZE);
301 // clear the paint buffer
302 memset(paintbuffer, 0, totalmixframes * sizeof(paintbuffer[0]));
304 // paint in the channels.
305 // channels with zero volumes still advance in time but don't paint.
306 ch = channels; // cppcheck complains here but it is wrong, channels is a channel_t[MAX_CHANNELS] and not an int
307 for (channelindex = 0;channelindex < (int)total_channels;channelindex++, ch++)
312 if (!S_LoadSound (sfx, true))
314 if (ch->flags & CHANNELFLAG_PAUSED)
316 if (!sfx->total_length)
319 // copy the channel information to the stack for reference, otherwise the
320 // values might change during a mix if the spatializer is updating them
321 // (note: this still may get some old and some new values!)
323 speedd = ch->mixspeed * sfx->format.speed / snd_renderbuffer->format.speed;
324 for (i = 0;i < SND_LISTENERS;i++)
325 vol[i] = ch->volume[i];
327 // check total volume level, because we can skip some code on silent sounds but other code must still run (position updates mainly)
329 for (i = 0;i < SND_LISTENERS;i++)
332 switch(snd_renderbuffer->format.width)
335 silent = maxvol < (1.0f / (256.0f));
336 // so silent it has zero effect
339 silent = maxvol < (1.0f / (65536.0f));
340 // so silent it has zero effect
342 default: // floating point
343 silent = maxvol < 1.0e-13f;
344 // 130 dB is difference between hearing
345 // threshold and a jackhammer from
347 // therefore, anyone who turns up
348 // volume so much they notice this
349 // cutoff, likely already has their
350 // ear-drums blown out anyway.
354 // when doing prologic mixing, some channels invert one side
355 if (ch->prologic_invert == -1)
358 // get some sfx info in a consistent form
359 totallength = sfx->total_length;
360 loopstart = (int)sfx->loopstart < totallength ? (int)sfx->loopstart : ((ch->flags & CHANNELFLAG_FORCELOOP) ? 0 : totallength);
361 looping = loopstart < totallength;
363 // do the actual paint now (may skip work if silent)
366 for (wantframes = totalmixframes;wantframes > 0;posd += count * speedd, wantframes -= count)
368 // check if this is a delayed sound
371 // for a delayed sound we have to eat into the delay first
372 count = (int)floor(-posd / speedd) + 1;
373 count = bound(1, count, wantframes);
374 // let the for loop iterator apply the skip
378 // compute a fetch size that won't overflow our buffer
382 istartframe = (int)floor(posd);
383 iendframe = (int)floor(posd + (count-1) * speedd);
384 ilengthframes = count > 1 ? (iendframe - istartframe + 2) : 2;
385 if (ilengthframes <= S_FETCHBUFFERSIZE)
387 // reduce count by 25% and try again
391 // zero whole fetch buffer for safety
392 // (floating point noise from uninitialized memory = HORRIBLE)
393 // otherwise we would only need to clear the excess
395 memset(fetchsampleframes, 0, ilengthframes*sfx->format.channels*sizeof(fetchsampleframes[0]));
397 // if looping, do multiple fetches
401 fetch = min(ilengthframes - fetched, totallength - istartframe);
405 sfx->fetcher->getsamplesfloat(ch, sfx, istartframe, fetch, fetchsampleframes + fetched*sfx->format.channels);
406 istartframe += fetch;
409 if (istartframe == totallength && looping && fetched < ilengthframes)
411 // loop and fetch some more
412 posd += loopstart - totallength;
413 istartframe = loopstart;
421 // set up our fixedpoint resampling variables (float to int conversions are expensive so do not do one per sampleframe)
422 fetchsampleframe = fetchsampleframes;
423 indexfrac = (int)floor((posd - floor(posd)) * 65536.0);
424 indexfracstep = (int)floor(speedd * 65536.0);
427 if (sfx->format.channels == 2)
430 #if SND_LISTENERS != 8
431 #error the following code only supports up to 8 channels, update it
433 if (snd_speakerlayout.channels > 2)
436 for (i = 0;i < count;i++, paint++)
438 lerp[1] = indexfrac * (1.0f / 65536.0f);
439 lerp[0] = 1.0f - lerp[1];
440 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
441 sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
442 sample[2] = (sample[0] + sample[1]) * 0.5f;
443 paint->sample[0] += sample[0] * vol[0];
444 paint->sample[1] += sample[1] * vol[1];
445 paint->sample[2] += sample[0] * vol[2];
446 paint->sample[3] += sample[1] * vol[3];
447 paint->sample[4] += sample[2] * vol[4];
448 paint->sample[5] += sample[2] * vol[5];
449 paint->sample[6] += sample[0] * vol[6];
450 paint->sample[7] += sample[1] * vol[7];
451 indexfrac += indexfracstep;
452 fetchsampleframe += 2 * (indexfrac >> 16);
459 for (i = 0;i < count;i++, paint++)
461 lerp[1] = indexfrac * (1.0f / 65536.0f);
462 lerp[0] = 1.0f - lerp[1];
463 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
464 sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
465 paint->sample[0] += sample[0] * vol[0];
466 paint->sample[1] += sample[1] * vol[1];
467 indexfrac += indexfracstep;
468 fetchsampleframe += 2 * (indexfrac >> 16);
473 else if (sfx->format.channels == 1)
475 // most sounds are mono
476 #if SND_LISTENERS != 8
477 #error the following code only supports up to 8 channels, update it
479 if (snd_speakerlayout.channels > 2)
482 for (i = 0;i < count;i++, paint++)
484 lerp[1] = indexfrac * (1.0f / 65536.0f);
485 lerp[0] = 1.0f - lerp[1];
486 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
487 paint->sample[0] += sample[0] * vol[0];
488 paint->sample[1] += sample[0] * vol[1];
489 paint->sample[2] += sample[0] * vol[2];
490 paint->sample[3] += sample[0] * vol[3];
491 paint->sample[4] += sample[0] * vol[4];
492 paint->sample[5] += sample[0] * vol[5];
493 paint->sample[6] += sample[0] * vol[6];
494 paint->sample[7] += sample[0] * vol[7];
495 indexfrac += indexfracstep;
496 fetchsampleframe += (indexfrac >> 16);
503 for (i = 0;i < count;i++, paint++)
505 lerp[1] = indexfrac * (1.0f / 65536.0f);
506 lerp[0] = 1.0f - lerp[1];
507 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
508 paint->sample[0] += sample[0] * vol[0];
509 paint->sample[1] += sample[0] * vol[1];
510 indexfrac += indexfracstep;
511 fetchsampleframe += (indexfrac >> 16);
519 if (!looping && istartframe == totallength)
520 S_StopChannel(ch - channels, false, false);
523 S_SoftClipPaintBuffer(paintbuffer, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
525 #ifdef CONFIG_VIDEO_CAPTURE
526 if (!snd_usethreadedmixing)
527 S_CaptureAVISound(paintbuffer, totalmixframes);
530 S_ConvertPaintBuffer(paintbuffer, outbytes, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
532 // advance the output pointer
533 outbytes += totalmixframes * snd_renderbuffer->format.width * snd_renderbuffer->format.channels;
534 bufferframes -= totalmixframes;