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 static void S_CaptureAVISound(const portable_sampleframe_t *paintbuffer, 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 extern cvar_t snd_softclip;
52 static void S_SoftClipPaintBuffer(portable_sampleframe_t *painted_ptr, int nbframes, int width, int channels)
56 if((snd_softclip.integer == 1 && width <= 2) || snd_softclip.integer > 1)
58 portable_sampleframe_t *p = painted_ptr;
61 /* Soft clipping, the sound of a dream, thanks to Jon Wattes
62 post to Musicdsp.org */
63 #define SOFTCLIP(x) (x) = sin(bound(-M_PI/2, (x), M_PI/2)) * 0.25
66 // let's do a simple limiter instead, seems to sound better
67 static float maxvol = 0;
68 maxvol = max(1.0f, maxvol * (1.0f - nbframes / (0.4f * snd_renderbuffer->format.speed)));
69 #define SOFTCLIP(x) if(fabs(x)>maxvol) maxvol=fabs(x); (x) /= maxvol;
71 if (channels == 8) // 7.1 surround
73 for (i = 0;i < nbframes;i++, p++)
75 SOFTCLIP(p->sample[0]);
76 SOFTCLIP(p->sample[1]);
77 SOFTCLIP(p->sample[2]);
78 SOFTCLIP(p->sample[3]);
79 SOFTCLIP(p->sample[4]);
80 SOFTCLIP(p->sample[5]);
81 SOFTCLIP(p->sample[6]);
82 SOFTCLIP(p->sample[7]);
85 else if (channels == 6) // 5.1 surround
87 for (i = 0; i < nbframes; i++, p++)
89 SOFTCLIP(p->sample[0]);
90 SOFTCLIP(p->sample[1]);
91 SOFTCLIP(p->sample[2]);
92 SOFTCLIP(p->sample[3]);
93 SOFTCLIP(p->sample[4]);
94 SOFTCLIP(p->sample[5]);
97 else if (channels == 4) // 4.0 surround
99 for (i = 0; i < nbframes; i++, p++)
101 SOFTCLIP(p->sample[0]);
102 SOFTCLIP(p->sample[1]);
103 SOFTCLIP(p->sample[2]);
104 SOFTCLIP(p->sample[3]);
107 else if (channels == 2) // 2.0 stereo
109 for (i = 0; i < nbframes; i++, p++)
111 SOFTCLIP(p->sample[0]);
112 SOFTCLIP(p->sample[1]);
115 else if (channels == 1) // 1.0 mono
117 for (i = 0; i < nbframes; i++, p++)
119 SOFTCLIP(p->sample[0]);
126 static void S_ConvertPaintBuffer(portable_sampleframe_t *painted_ptr, void *rb_ptr, int nbframes, int width, int channels)
130 // FIXME: add 24bit and 32bit float formats
131 // FIXME: optimize with SSE intrinsics?
132 if (width == 2) // 16bit
134 short *snd_out = (short*)rb_ptr;
135 if (channels == 8) // 7.1 surround
137 for (i = 0;i < nbframes;i++, painted_ptr++)
139 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
140 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
141 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
142 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
143 val = (int)(painted_ptr->sample[4] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
144 val = (int)(painted_ptr->sample[5] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
145 val = (int)(painted_ptr->sample[6] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
146 val = (int)(painted_ptr->sample[7] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
149 else if (channels == 6) // 5.1 surround
151 for (i = 0; i < nbframes; i++, painted_ptr++)
153 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
154 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
155 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
156 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
157 val = (int)(painted_ptr->sample[4] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
158 val = (int)(painted_ptr->sample[5] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
161 else if (channels == 4) // 4.0 surround
163 for (i = 0; i < nbframes; i++, painted_ptr++)
165 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
166 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
167 val = (int)(painted_ptr->sample[2] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
168 val = (int)(painted_ptr->sample[3] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
171 else if (channels == 2) // 2.0 stereo
173 for (i = 0; i < nbframes; i++, painted_ptr++)
175 val = (int)(painted_ptr->sample[0] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
176 val = (int)(painted_ptr->sample[1] * 32768.0f);*snd_out++ = bound(-32768, val, 32767);
179 else if (channels == 1) // 1.0 mono
181 for (i = 0; i < nbframes; i++, painted_ptr++)
183 val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 16384.0f);*snd_out++ = bound(-32768, val, 32767);
187 // noise is really really annoying
189 memset(rb_ptr, 0, nbframes * channels * width);
193 unsigned char *snd_out = (unsigned char*)rb_ptr;
194 if (channels == 8) // 7.1 surround
196 for (i = 0; i < nbframes; i++, painted_ptr++)
198 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
199 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
200 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
201 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
202 val = (int)(painted_ptr->sample[4] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
203 val = (int)(painted_ptr->sample[5] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
204 val = (int)(painted_ptr->sample[6] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
205 val = (int)(painted_ptr->sample[7] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
208 else if (channels == 6) // 5.1 surround
210 for (i = 0; i < nbframes; i++, painted_ptr++)
212 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
213 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
214 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
215 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
216 val = (int)(painted_ptr->sample[4] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
217 val = (int)(painted_ptr->sample[5] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
220 else if (channels == 4) // 4.0 surround
222 for (i = 0; i < nbframes; i++, painted_ptr++)
224 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
225 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
226 val = (int)(painted_ptr->sample[2] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
227 val = (int)(painted_ptr->sample[3] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
230 else if (channels == 2) // 2.0 stereo
232 for (i = 0; i < nbframes; i++, painted_ptr++)
234 val = (int)(painted_ptr->sample[0] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
235 val = (int)(painted_ptr->sample[1] * 128.0f) + 128; *snd_out++ = bound(0, val, 255);
238 else if (channels == 1) // 1.0 mono
240 for (i = 0;i < nbframes;i++, painted_ptr++)
242 val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 64.0f) + 128; *snd_out++ = bound(0, val, 255);
246 // noise is really really annoying
248 memset(rb_ptr, 128, nbframes * channels);
254 ===============================================================================
258 ===============================================================================
261 void S_MixToBuffer(void *stream, unsigned int bufferframes)
266 unsigned char *outbytes = (unsigned char *) stream;
268 portable_sampleframe_t *paint;
281 #define S_FETCHBUFFERSIZE 4096
282 float fetchsampleframes[S_FETCHBUFFERSIZE*2];
283 const float *fetchsampleframe;
284 float vol[SND_LISTENERS];
293 // mix as many times as needed to fill the requested buffer
296 // limit to the size of the paint buffer
297 totalmixframes = min(bufferframes, PAINTBUFFER_SIZE);
299 // clear the paint buffer
300 memset(paintbuffer, 0, totalmixframes * sizeof(paintbuffer[0]));
302 // paint in the channels.
303 // channels with zero volumes still advance in time but don't paint.
304 ch = channels; // cppcheck complains here but it is wrong, channels is a channel_t[MAX_CHANNELS] and not an int
305 for (channelindex = 0;channelindex < (int)total_channels;channelindex++, ch++)
310 if (!S_LoadSound (sfx, true))
312 if (ch->flags & CHANNELFLAG_PAUSED)
314 if (!sfx->total_length)
317 // copy the channel information to the stack for reference, otherwise the
318 // values might change during a mix if the spatializer is updating them
319 // (note: this still may get some old and some new values!)
321 speedd = ch->mixspeed * sfx->format.speed / snd_renderbuffer->format.speed;
322 for (i = 0;i < SND_LISTENERS;i++)
323 vol[i] = ch->volume[i];
325 // check total volume level, because we can skip some code on silent sounds but other code must still run (position updates mainly)
327 for (i = 0;i < SND_LISTENERS;i++)
330 switch(snd_renderbuffer->format.width)
333 silent = maxvol < (1.0f / (256.0f));
334 // so silent it has zero effect
337 silent = maxvol < (1.0f / (65536.0f));
338 // so silent it has zero effect
340 default: // floating point
341 silent = maxvol < 1.0e-13f;
342 // 130 dB is difference between hearing
343 // threshold and a jackhammer from
345 // therefore, anyone who turns up
346 // volume so much they notice this
347 // cutoff, likely already has their
348 // ear-drums blown out anyway.
352 // when doing prologic mixing, some channels invert one side
353 if (ch->prologic_invert == -1)
356 // get some sfx info in a consistent form
357 totallength = sfx->total_length;
358 loopstart = (int)sfx->loopstart < totallength ? (int)sfx->loopstart : ((ch->flags & CHANNELFLAG_FORCELOOP) ? 0 : totallength);
359 looping = loopstart < totallength;
361 // do the actual paint now (may skip work if silent)
364 for (wantframes = totalmixframes;wantframes > 0;posd += count * speedd, wantframes -= count)
366 // check if this is a delayed sound
369 // for a delayed sound we have to eat into the delay first
370 count = (int)floor(-posd / speedd) + 1;
371 count = bound(1, count, wantframes);
372 // let the for loop iterator apply the skip
376 // compute a fetch size that won't overflow our buffer
380 istartframe = (int)floor(posd);
381 iendframe = (int)floor(posd + (count-1) * speedd);
382 ilengthframes = count > 1 ? (iendframe - istartframe + 2) : 2;
383 if (ilengthframes <= S_FETCHBUFFERSIZE)
385 // reduce count by 25% and try again
389 // zero whole fetch buffer for safety
390 // (floating point noise from uninitialized memory = HORRIBLE)
391 // otherwise we would only need to clear the excess
393 memset(fetchsampleframes, 0, ilengthframes*sfx->format.channels*sizeof(fetchsampleframes[0]));
395 // if looping, do multiple fetches
399 fetch = min(ilengthframes - fetched, totallength - istartframe);
403 sfx->fetcher->getsamplesfloat(ch, sfx, istartframe, fetch, fetchsampleframes + fetched*sfx->format.channels);
404 istartframe += fetch;
407 if (istartframe == totallength && looping && fetched < ilengthframes)
409 // loop and fetch some more
410 posd += loopstart - totallength;
411 istartframe = loopstart;
419 // set up our fixedpoint resampling variables (float to int conversions are expensive so do not do one per sampleframe)
420 fetchsampleframe = fetchsampleframes;
421 indexfrac = (int)floor((posd - floor(posd)) * 65536.0);
422 indexfracstep = (int)floor(speedd * 65536.0);
425 if (sfx->format.channels == 2)
428 #if SND_LISTENERS != 8
429 #error the following code only supports up to 8 channels, update it
431 if (snd_speakerlayout.channels > 2)
434 for (i = 0;i < count;i++, paint++)
436 lerp[1] = indexfrac * (1.0f / 65536.0f);
437 lerp[0] = 1.0f - lerp[1];
438 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
439 sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
440 sample[2] = (sample[0] + sample[1]) * 0.5f;
441 paint->sample[0] += sample[0] * vol[0];
442 paint->sample[1] += sample[1] * vol[1];
443 paint->sample[2] += sample[0] * vol[2];
444 paint->sample[3] += sample[1] * vol[3];
445 paint->sample[4] += sample[2] * vol[4];
446 paint->sample[5] += sample[2] * vol[5];
447 paint->sample[6] += sample[0] * vol[6];
448 paint->sample[7] += sample[1] * vol[7];
449 indexfrac += indexfracstep;
450 fetchsampleframe += 2 * (indexfrac >> 16);
457 for (i = 0;i < count;i++, paint++)
459 lerp[1] = indexfrac * (1.0f / 65536.0f);
460 lerp[0] = 1.0f - lerp[1];
461 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[2] * lerp[1];
462 sample[1] = fetchsampleframe[1] * lerp[0] + fetchsampleframe[3] * lerp[1];
463 paint->sample[0] += sample[0] * vol[0];
464 paint->sample[1] += sample[1] * vol[1];
465 indexfrac += indexfracstep;
466 fetchsampleframe += 2 * (indexfrac >> 16);
471 else if (sfx->format.channels == 1)
473 // most sounds are mono
474 #if SND_LISTENERS != 8
475 #error the following code only supports up to 8 channels, update it
477 if (snd_speakerlayout.channels > 2)
480 for (i = 0;i < count;i++, paint++)
482 lerp[1] = indexfrac * (1.0f / 65536.0f);
483 lerp[0] = 1.0f - lerp[1];
484 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
485 paint->sample[0] += sample[0] * vol[0];
486 paint->sample[1] += sample[0] * vol[1];
487 paint->sample[2] += sample[0] * vol[2];
488 paint->sample[3] += sample[0] * vol[3];
489 paint->sample[4] += sample[0] * vol[4];
490 paint->sample[5] += sample[0] * vol[5];
491 paint->sample[6] += sample[0] * vol[6];
492 paint->sample[7] += sample[0] * vol[7];
493 indexfrac += indexfracstep;
494 fetchsampleframe += (indexfrac >> 16);
501 for (i = 0;i < count;i++, paint++)
503 lerp[1] = indexfrac * (1.0f / 65536.0f);
504 lerp[0] = 1.0f - lerp[1];
505 sample[0] = fetchsampleframe[0] * lerp[0] + fetchsampleframe[1] * lerp[1];
506 paint->sample[0] += sample[0] * vol[0];
507 paint->sample[1] += sample[0] * vol[1];
508 indexfrac += indexfracstep;
509 fetchsampleframe += (indexfrac >> 16);
517 if (!looping && istartframe == totallength)
518 S_StopChannel(ch - channels, false, false);
521 S_SoftClipPaintBuffer(paintbuffer, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
523 if (!snd_usethreadedmixing)
524 S_CaptureAVISound(paintbuffer, totalmixframes);
526 S_ConvertPaintBuffer(paintbuffer, outbytes, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
528 // advance the output pointer
529 outbytes += totalmixframes * snd_renderbuffer->format.width * snd_renderbuffer->format.channels;
530 bufferframes -= totalmixframes;