]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - snd_mix.c
disable depthfirst rendering on animated models since it doesn't work and should...
[xonotic/darkplaces.git] / snd_mix.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
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.
8
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.
12
13 See the GNU General Public License for more details.
14
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.
18
19 */
20
21 #include "quakedef.h"
22 #include "snd_main.h"
23
24 extern cvar_t snd_softclip;
25
26 static portable_sampleframe_t paintbuffer[PAINTBUFFER_SIZE];
27 static portable_sampleframe_t paintbuffer_unswapped[PAINTBUFFER_SIZE];
28
29 extern speakerlayout_t snd_speakerlayout; // for querying the listeners
30
31 static void S_CaptureAVISound(const portable_sampleframe_t *paintbuffer, size_t length)
32 {
33         size_t i;
34         unsigned int j;
35
36         if (!cls.capturevideo.active)
37                 return;
38
39         // undo whatever swapping the channel layout (swapstereo, ALSA) did
40         for(j = 0; j < snd_speakerlayout.channels; ++j)
41         {
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];
45         }
46
47         SCR_CaptureVideo_SoundFrame(paintbuffer_unswapped, length);
48 }
49
50 extern cvar_t snd_softclip;
51
52 static void S_SoftClipPaintBuffer(portable_sampleframe_t *painted_ptr, int nbframes, int width, int channels)
53 {
54         int i;
55
56         if((snd_softclip.integer == 1 && width <= 2) || snd_softclip.integer > 1)
57         {
58                 portable_sampleframe_t *p = painted_ptr;
59
60 #if 0
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
64 #endif
65
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;
70
71                 if (channels == 8)  // 7.1 surround
72                 {
73                         for (i = 0;i < nbframes;i++, p++)
74                         {
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]);
83                         }
84                 }
85                 else if (channels == 6)  // 5.1 surround
86                 {
87                         for (i = 0; i < nbframes; i++, p++)
88                         {
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]);
95                         }
96                 }
97                 else if (channels == 4)  // 4.0 surround
98                 {
99                         for (i = 0; i < nbframes; i++, p++)
100                         {
101                                 SOFTCLIP(p->sample[0]);
102                                 SOFTCLIP(p->sample[1]);
103                                 SOFTCLIP(p->sample[2]);
104                                 SOFTCLIP(p->sample[3]);
105                         }
106                 }
107                 else if (channels == 2)  // 2.0 stereo
108                 {
109                         for (i = 0; i < nbframes; i++, p++)
110                         {
111                                 SOFTCLIP(p->sample[0]);
112                                 SOFTCLIP(p->sample[1]);
113                         }
114                 }
115                 else if (channels == 1)  // 1.0 mono
116                 {
117                         for (i = 0; i < nbframes; i++, p++)
118                         {
119                                 SOFTCLIP(p->sample[0]);
120                         }
121                 }
122 #undef SOFTCLIP
123         }
124 }
125
126 static void S_ConvertPaintBuffer(portable_sampleframe_t *painted_ptr, void *rb_ptr, int nbframes, int width, int channels)
127 {
128         int i, val;
129
130         // FIXME: add 24bit and 32bit float formats
131         // FIXME: optimize with SSE intrinsics?
132         if (width == 2)  // 16bit
133         {
134                 short *snd_out = (short*)rb_ptr;
135                 if (channels == 8)  // 7.1 surround
136                 {
137                         for (i = 0;i < nbframes;i++, painted_ptr++)
138                         {
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);
147                         }
148                 }
149                 else if (channels == 6)  // 5.1 surround
150                 {
151                         for (i = 0; i < nbframes; i++, painted_ptr++)
152                         {
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);
159                         }
160                 }
161                 else if (channels == 4)  // 4.0 surround
162                 {
163                         for (i = 0; i < nbframes; i++, painted_ptr++)
164                         {
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);
169                         }
170                 }
171                 else if (channels == 2)  // 2.0 stereo
172                 {
173                         for (i = 0; i < nbframes; i++, painted_ptr++)
174                         {
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);
177                         }
178                 }
179                 else if (channels == 1)  // 1.0 mono
180                 {
181                         for (i = 0; i < nbframes; i++, painted_ptr++)
182                         {
183                                 val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 16384.0f);*snd_out++ = bound(-32768, val, 32767);
184                         }
185                 }
186
187                 // noise is really really annoying
188                 if (cls.timedemo)
189                         memset(rb_ptr, 0, nbframes * channels * width);
190         }
191         else  // 8bit
192         {
193                 unsigned char *snd_out = (unsigned char*)rb_ptr;
194                 if (channels == 8)  // 7.1 surround
195                 {
196                         for (i = 0; i < nbframes; i++, painted_ptr++)
197                         {
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);
206                         }
207                 }
208                 else if (channels == 6)  // 5.1 surround
209                 {
210                         for (i = 0; i < nbframes; i++, painted_ptr++)
211                         {
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);
218                         }
219                 }
220                 else if (channels == 4)  // 4.0 surround
221                 {
222                         for (i = 0; i < nbframes; i++, painted_ptr++)
223                         {
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);
228                         }
229                 }
230                 else if (channels == 2)  // 2.0 stereo
231                 {
232                         for (i = 0; i < nbframes; i++, painted_ptr++)
233                         {
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);
236                         }
237                 }
238                 else if (channels == 1)  // 1.0 mono
239                 {
240                         for (i = 0;i < nbframes;i++, painted_ptr++)
241                         {
242                                 val = (int)((painted_ptr->sample[0] + painted_ptr->sample[1]) * 64.0f) + 128; *snd_out++ = bound(0, val, 255);
243                         }
244                 }
245
246                 // noise is really really annoying
247                 if (cls.timedemo)
248                         memset(rb_ptr, 128, nbframes * channels);
249         }
250 }
251
252
253 /*
254 ===============================================================================
255
256 CHANNEL MIXING
257
258 ===============================================================================
259 */
260
261 void S_MixToBuffer(void *stream, unsigned int bufferframes)
262 {
263         int channelindex;
264         channel_t *ch;
265         int totalmixframes;
266         unsigned char *outbytes = (unsigned char *) stream;
267         sfx_t *sfx;
268         portable_sampleframe_t *paint;
269         int wantframes;
270         int i;
271         int count;
272         int fetched;
273         int fetch;
274         int istartframe;
275         int iendframe;
276         int ilengthframes;
277         int totallength;
278         int loopstart;
279         int indexfrac;
280         int indexfracstep;
281 #define S_FETCHBUFFERSIZE 4096
282         float fetchsampleframes[S_FETCHBUFFERSIZE*2];
283         const float *fetchsampleframe;
284         float vol[SND_LISTENERS];
285         float lerp[2];
286         float sample[3];
287         double posd;
288         double speedd;
289         float maxvol;
290         qboolean looping;
291         qboolean silent;
292
293         // mix as many times as needed to fill the requested buffer
294         while (bufferframes)
295         {
296                 // limit to the size of the paint buffer
297                 totalmixframes = min(bufferframes, PAINTBUFFER_SIZE);
298
299                 // clear the paint buffer
300                 memset(paintbuffer, 0, totalmixframes * sizeof(paintbuffer[0]));
301
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++)
306                 {
307                         sfx = ch->sfx;
308                         if (sfx == NULL)
309                                 continue;
310                         if (!S_LoadSound (sfx, true))
311                                 continue;
312                         if (ch->flags & CHANNELFLAG_PAUSED)
313                                 continue;
314                         if (!sfx->total_length)
315                                 continue;
316
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!)
320                         posd = ch->position;
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];
324
325                         // check total volume level, because we can skip some code on silent sounds but other code must still run (position updates mainly)
326                         maxvol = 0;
327                         for (i = 0;i < SND_LISTENERS;i++)
328                                 if(vol[i] > maxvol)
329                                         maxvol = vol[i];
330                         switch(snd_renderbuffer->format.width)
331                         {
332                                 case 1: // 8bpp
333                                         silent = maxvol < (1.0f / (256.0f));
334                                         // so silent it has zero effect
335                                         break;
336                                 case 2: // 16bpp
337                                         silent = maxvol < (1.0f / (65536.0f));
338                                         // so silent it has zero effect
339                                         break;
340                                 default: // floating point
341                                         silent = maxvol < 1.0e-13f;
342                                         // 130 dB is difference between hearing
343                                         // threshold and a jackhammer from
344                                         // working distance.
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.
349                                         break;
350                         }
351
352                         // when doing prologic mixing, some channels invert one side
353                         if (ch->prologic_invert == -1)
354                                 vol[1] *= -1.0f;
355
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;
360
361                         // do the actual paint now (may skip work if silent)
362                         paint = paintbuffer;
363                         istartframe = 0;
364                         for (wantframes = totalmixframes;wantframes > 0;posd += count * speedd, wantframes -= count)
365                         {
366                                 // check if this is a delayed sound
367                                 if (posd < 0)
368                                 {
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
373                                         continue;
374                                 }
375
376                                 // compute a fetch size that won't overflow our buffer
377                                 count = wantframes;
378                                 for (;;)
379                                 {
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)
384                                                 break;
385                                         // reduce count by 25% and try again
386                                         count -= count >> 2;
387                                 }
388
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
392                                 if (!silent)
393                                         memset(fetchsampleframes, 0, ilengthframes*sfx->format.channels*sizeof(fetchsampleframes[0]));
394
395                                 // if looping, do multiple fetches
396                                 fetched = 0;
397                                 for (;;)
398                                 {
399                                         fetch = min(ilengthframes - fetched, totallength - istartframe);
400                                         if (fetch > 0)
401                                         {
402                                                 if (!silent)
403                                                         sfx->fetcher->getsamplesfloat(ch, sfx, istartframe, fetch, fetchsampleframes + fetched*sfx->format.channels);
404                                                 istartframe += fetch;
405                                                 fetched += fetch;
406                                         }
407                                         if (istartframe == totallength && looping && fetched < ilengthframes)
408                                         {
409                                                 // loop and fetch some more
410                                                 posd += loopstart - totallength;
411                                                 istartframe = loopstart;
412                                         }
413                                         else
414                                         {
415                                                 break;
416                                         }
417                                 }
418
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);
423                                 if (!silent)
424                                 {
425                                         if (sfx->format.channels == 2)
426                                         {
427                                                 // music is stereo
428 #if SND_LISTENERS != 8
429 #error the following code only supports up to 8 channels, update it
430 #endif
431                                                 if (snd_speakerlayout.channels > 2)
432                                                 {
433                                                         // surround mixing
434                                                         for (i = 0;i < count;i++, paint++)
435                                                         {
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);
451                                                                 indexfrac &= 0xFFFF;
452                                                         }
453                                                 }
454                                                 else
455                                                 {
456                                                         // stereo mixing
457                                                         for (i = 0;i < count;i++, paint++)
458                                                         {
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);
467                                                                 indexfrac &= 0xFFFF;
468                                                         }
469                                                 }
470                                         }
471                                         else if (sfx->format.channels == 1)
472                                         {
473                                                 // most sounds are mono
474 #if SND_LISTENERS != 8
475 #error the following code only supports up to 8 channels, update it
476 #endif
477                                                 if (snd_speakerlayout.channels > 2)
478                                                 {
479                                                         // surround mixing
480                                                         for (i = 0;i < count;i++, paint++)
481                                                         {
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);
495                                                                 indexfrac &= 0xFFFF;
496                                                         }
497                                                 }
498                                                 else
499                                                 {
500                                                         // stereo mixing
501                                                         for (i = 0;i < count;i++, paint++)
502                                                         {
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);
510                                                                 indexfrac &= 0xFFFF;
511                                                         }
512                                                 }
513                                         }
514                                 }
515                         }
516                         ch->position = posd;
517                         if (!looping && istartframe == totallength)
518                                 S_StopChannel(ch - channels, false, false);
519                 }
520
521                 S_SoftClipPaintBuffer(paintbuffer, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
522
523                 if (!snd_usethreadedmixing)
524                         S_CaptureAVISound(paintbuffer, totalmixframes);
525
526                 S_ConvertPaintBuffer(paintbuffer, outbytes, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
527
528                 // advance the output pointer
529                 outbytes += totalmixframes * snd_renderbuffer->format.width * snd_renderbuffer->format.channels;
530                 bufferframes -= totalmixframes;
531         }
532 }