]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - snd_mix.c
fixed loadgame to support stock quake savegames (which have 64 lightstyles, darkplace...
[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 // snd_mix.c -- portable code to mix sounds
21
22 #include "quakedef.h"
23 #include "snd_main.h"
24
25 typedef struct portable_samplepair_s
26 {
27         int sample[SND_LISTENERS];
28 } portable_sampleframe_t;
29
30 // LordHavoc: was 512, expanded to 2048
31 #define PAINTBUFFER_SIZE 2048
32 portable_sampleframe_t paintbuffer[PAINTBUFFER_SIZE];
33
34 // FIXME: this desyncs with the video too easily
35 extern qboolean cl_capturevideo_active;
36 extern void SCR_CaptureVideo_SoundFrame(unsigned char *bufstereo16le, size_t length, int rate);
37 void S_CaptureAVISound(portable_sampleframe_t *buf, size_t length)
38 {
39         int n;
40         size_t i;
41         unsigned char out[PAINTBUFFER_SIZE * 4];
42         if (!cl_capturevideo_active)
43                 return;
44         // write the sound buffer as little endian 16bit interleaved stereo
45         for(i = 0;i < length;i++)
46         {
47                 n = buf[i].sample[0];
48                 n = bound(-32768, n, 32767);
49                 out[i*4+0] = n & 0xFF;
50                 out[i*4+1] = (n >> 8) & 0xFF;
51                 n = buf[i].sample[1];
52                 n = bound(-32768, n, 32767);
53                 out[i*4+2] = n & 0xFF;
54                 out[i*4+3] = (n >> 8) & 0xFF;
55         }
56         SCR_CaptureVideo_SoundFrame(out, length, shm->format.speed);
57 }
58
59 // TODO: rewrite this function
60 void S_TransferPaintBuffer(int endtime)
61 {
62         void *pbuf;
63         int i;
64         portable_sampleframe_t *snd_p;
65         int lpaintedtime;
66         int snd_frames;
67         int val;
68         if ((pbuf = S_LockBuffer()))
69         {
70                 snd_p = paintbuffer;
71                 lpaintedtime = paintedtime;
72                 for (lpaintedtime = paintedtime;lpaintedtime < endtime;lpaintedtime += snd_frames)
73                 {
74                         // handle recirculating buffer issues
75                         i = lpaintedtime & (shm->sampleframes - 1);
76                         snd_frames = shm->sampleframes - i;
77                         if (snd_frames > endtime - lpaintedtime)
78                                 snd_frames = endtime - lpaintedtime;
79                         if (shm->format.width == 2)
80                         {
81                                 // 16bit
82                                 short *snd_out = (short *) pbuf + i * shm->format.channels;
83                                 if (shm->format.channels == 8)
84                                 {
85                                         // 7.1 surround
86                                         if (snd_swapstereo.value)
87                                         {
88                                                 for (i = 0;i < snd_frames;i++, snd_p++)
89                                                 {
90                                                         *snd_out++ = bound(-32768, snd_p->sample[1], 32767);
91                                                         *snd_out++ = bound(-32768, snd_p->sample[0], 32767);
92                                                         *snd_out++ = bound(-32768, snd_p->sample[3], 32767);
93                                                         *snd_out++ = bound(-32768, snd_p->sample[2], 32767);
94                                                         *snd_out++ = bound(-32768, snd_p->sample[4], 32767);
95                                                         *snd_out++ = bound(-32768, snd_p->sample[5], 32767);
96                                                         *snd_out++ = bound(-32768, snd_p->sample[6], 32767);
97                                                         *snd_out++ = bound(-32768, snd_p->sample[7], 32767);
98                                                 }
99                                         }
100                                         else
101                                         {
102                                                 for (i = 0;i < snd_frames;i++, snd_p++)
103                                                 {
104                                                         *snd_out++ = bound(-32768, snd_p->sample[0], 32767);
105                                                         *snd_out++ = bound(-32768, snd_p->sample[1], 32767);
106                                                         *snd_out++ = bound(-32768, snd_p->sample[2], 32767);
107                                                         *snd_out++ = bound(-32768, snd_p->sample[3], 32767);
108                                                         *snd_out++ = bound(-32768, snd_p->sample[4], 32767);
109                                                         *snd_out++ = bound(-32768, snd_p->sample[5], 32767);
110                                                         *snd_out++ = bound(-32768, snd_p->sample[6], 32767);
111                                                         *snd_out++ = bound(-32768, snd_p->sample[7], 32767);
112                                                 }
113                                         }
114                                 }
115                                 else if (shm->format.channels == 6)
116                                 {
117                                         // 5.1 surround
118                                         if (snd_swapstereo.value)
119                                         {
120                                                 for (i = 0;i < snd_frames;i++, snd_p++)
121                                                 {
122                                                         *snd_out++ = bound(-32768, snd_p->sample[1], 32767);
123                                                         *snd_out++ = bound(-32768, snd_p->sample[0], 32767);
124                                                         *snd_out++ = bound(-32768, snd_p->sample[3], 32767);
125                                                         *snd_out++ = bound(-32768, snd_p->sample[2], 32767);
126                                                         *snd_out++ = bound(-32768, snd_p->sample[4], 32767);
127                                                         *snd_out++ = bound(-32768, snd_p->sample[5], 32767);
128                                                 }
129                                         }
130                                         else
131                                         {
132                                                 for (i = 0;i < snd_frames;i++, snd_p++)
133                                                 {
134                                                         *snd_out++ = bound(-32768, snd_p->sample[0], 32767);
135                                                         *snd_out++ = bound(-32768, snd_p->sample[1], 32767);
136                                                         *snd_out++ = bound(-32768, snd_p->sample[2], 32767);
137                                                         *snd_out++ = bound(-32768, snd_p->sample[3], 32767);
138                                                         *snd_out++ = bound(-32768, snd_p->sample[4], 32767);
139                                                         *snd_out++ = bound(-32768, snd_p->sample[5], 32767);
140                                                 }
141                                         }
142                                 }
143                                 else if (shm->format.channels == 4)
144                                 {
145                                         // 4.0 surround
146                                         if (snd_swapstereo.value)
147                                         {
148                                                 for (i = 0;i < snd_frames;i++, snd_p++)
149                                                 {
150                                                         *snd_out++ = bound(-32768, snd_p->sample[1], 32767);
151                                                         *snd_out++ = bound(-32768, snd_p->sample[0], 32767);
152                                                         *snd_out++ = bound(-32768, snd_p->sample[3], 32767);
153                                                         *snd_out++ = bound(-32768, snd_p->sample[2], 32767);
154                                                 }
155                                         }
156                                         else
157                                         {
158                                                 for (i = 0;i < snd_frames;i++, snd_p++)
159                                                 {
160                                                         *snd_out++ = bound(-32768, snd_p->sample[0], 32767);
161                                                         *snd_out++ = bound(-32768, snd_p->sample[1], 32767);
162                                                         *snd_out++ = bound(-32768, snd_p->sample[2], 32767);
163                                                         *snd_out++ = bound(-32768, snd_p->sample[3], 32767);
164                                                 }
165                                         }
166                                 }
167                                 else if (shm->format.channels == 2)
168                                 {
169                                         // 2.0 stereo
170                                         if (snd_swapstereo.value)
171                                         {
172                                                 for (i = 0;i < snd_frames;i++, snd_p++)
173                                                 {
174                                                         *snd_out++ = bound(-32768, snd_p->sample[1], 32767);
175                                                         *snd_out++ = bound(-32768, snd_p->sample[0], 32767);
176                                                 }
177                                         }
178                                         else
179                                         {
180                                                 for (i = 0;i < snd_frames;i++, snd_p++)
181                                                 {
182                                                         *snd_out++ = bound(-32768, snd_p->sample[0], 32767);
183                                                         *snd_out++ = bound(-32768, snd_p->sample[1], 32767);
184                                                 }
185                                         }
186                                 }
187                                 else if (shm->format.channels == 1)
188                                 {
189                                         // 1.0 mono
190                                         for (i = 0;i < snd_frames;i++, snd_p++)
191                                                 *snd_out++ = bound(-32768, (snd_p->sample[0] + snd_p->sample[1]) >> 1, 32767);
192                                 }
193                         }
194                         else
195                         {
196                                 // 8bit
197                                 unsigned char *snd_out = (unsigned char *) pbuf + i * shm->format.channels;
198                                 if (shm->format.channels == 8)
199                                 {
200                                         // 7.1 surround
201                                         if (snd_swapstereo.value)
202                                         {
203                                                 for (i = 0;i < snd_frames;i++, snd_p++)
204                                                 {
205                                                         val = (snd_p->sample[1] >> 8) + 128;*snd_out++ = bound(0, val, 255);
206                                                         val = (snd_p->sample[0] >> 8) + 128;*snd_out++ = bound(0, val, 255);
207                                                         val = (snd_p->sample[3] >> 8) + 128;*snd_out++ = bound(0, val, 255);
208                                                         val = (snd_p->sample[2] >> 8) + 128;*snd_out++ = bound(0, val, 255);
209                                                         val = (snd_p->sample[4] >> 8) + 128;*snd_out++ = bound(0, val, 255);
210                                                         val = (snd_p->sample[5] >> 8) + 128;*snd_out++ = bound(0, val, 255);
211                                                         val = (snd_p->sample[6] >> 8) + 128;*snd_out++ = bound(0, val, 255);
212                                                         val = (snd_p->sample[7] >> 8) + 128;*snd_out++ = bound(0, val, 255);
213                                                 }
214                                         }
215                                         else
216                                         {
217                                                 for (i = 0;i < snd_frames;i++, snd_p++)
218                                                 {
219                                                         val = (snd_p->sample[0] >> 8) + 128;*snd_out++ = bound(0, val, 255);
220                                                         val = (snd_p->sample[1] >> 8) + 128;*snd_out++ = bound(0, val, 255);
221                                                         val = (snd_p->sample[2] >> 8) + 128;*snd_out++ = bound(0, val, 255);
222                                                         val = (snd_p->sample[3] >> 8) + 128;*snd_out++ = bound(0, val, 255);
223                                                         val = (snd_p->sample[4] >> 8) + 128;*snd_out++ = bound(0, val, 255);
224                                                         val = (snd_p->sample[5] >> 8) + 128;*snd_out++ = bound(0, val, 255);
225                                                         val = (snd_p->sample[6] >> 8) + 128;*snd_out++ = bound(0, val, 255);
226                                                         val = (snd_p->sample[7] >> 8) + 128;*snd_out++ = bound(0, val, 255);
227                                                 }
228                                         }
229                                 }
230                                 else if (shm->format.channels == 6)
231                                 {
232                                         // 5.1 surround
233                                         if (snd_swapstereo.value)
234                                         {
235                                                 for (i = 0;i < snd_frames;i++, snd_p++)
236                                                 {
237                                                         val = (snd_p->sample[1] >> 8) + 128;*snd_out++ = bound(0, val, 255);
238                                                         val = (snd_p->sample[0] >> 8) + 128;*snd_out++ = bound(0, val, 255);
239                                                         val = (snd_p->sample[3] >> 8) + 128;*snd_out++ = bound(0, val, 255);
240                                                         val = (snd_p->sample[2] >> 8) + 128;*snd_out++ = bound(0, val, 255);
241                                                         val = (snd_p->sample[4] >> 8) + 128;*snd_out++ = bound(0, val, 255);
242                                                         val = (snd_p->sample[5] >> 8) + 128;*snd_out++ = bound(0, val, 255);
243                                                 }
244                                         }
245                                         else
246                                         {
247                                                 for (i = 0;i < snd_frames;i++, snd_p++)
248                                                 {
249                                                         val = (snd_p->sample[0] >> 8) + 128;*snd_out++ = bound(0, val, 255);
250                                                         val = (snd_p->sample[1] >> 8) + 128;*snd_out++ = bound(0, val, 255);
251                                                         val = (snd_p->sample[2] >> 8) + 128;*snd_out++ = bound(0, val, 255);
252                                                         val = (snd_p->sample[3] >> 8) + 128;*snd_out++ = bound(0, val, 255);
253                                                         val = (snd_p->sample[4] >> 8) + 128;*snd_out++ = bound(0, val, 255);
254                                                         val = (snd_p->sample[5] >> 8) + 128;*snd_out++ = bound(0, val, 255);
255                                                 }
256                                         }
257                                 }
258                                 else if (shm->format.channels == 4)
259                                 {
260                                         // 4.0 surround
261                                         if (snd_swapstereo.value)
262                                         {
263                                                 for (i = 0;i < snd_frames;i++, snd_p++)
264                                                 {
265                                                         val = (snd_p->sample[1] >> 8) + 128;*snd_out++ = bound(0, val, 255);
266                                                         val = (snd_p->sample[0] >> 8) + 128;*snd_out++ = bound(0, val, 255);
267                                                         val = (snd_p->sample[3] >> 8) + 128;*snd_out++ = bound(0, val, 255);
268                                                         val = (snd_p->sample[2] >> 8) + 128;*snd_out++ = bound(0, val, 255);
269                                                 }
270                                         }
271                                         else
272                                         {
273                                                 for (i = 0;i < snd_frames;i++, snd_p++)
274                                                 {
275                                                         val = (snd_p->sample[0] >> 8) + 128;*snd_out++ = bound(0, val, 255);
276                                                         val = (snd_p->sample[1] >> 8) + 128;*snd_out++ = bound(0, val, 255);
277                                                         val = (snd_p->sample[2] >> 8) + 128;*snd_out++ = bound(0, val, 255);
278                                                         val = (snd_p->sample[3] >> 8) + 128;*snd_out++ = bound(0, val, 255);
279                                                 }
280                                         }
281                                 }
282                                 else if (shm->format.channels == 2)
283                                 {
284                                         // 2.0 stereo
285                                         if (snd_swapstereo.value)
286                                         {
287                                                 for (i = 0;i < snd_frames;i++, snd_p++)
288                                                 {
289                                                         val = (snd_p->sample[1] >> 8) + 128;*snd_out++ = bound(0, val, 255);
290                                                         val = (snd_p->sample[0] >> 8) + 128;*snd_out++ = bound(0, val, 255);
291                                                 }
292                                         }
293                                         else
294                                         {
295                                                 for (i = 0;i < snd_frames;i++, snd_p++)
296                                                 {
297                                                         val = (snd_p->sample[0] >> 8) + 128;*snd_out++ = bound(0, val, 255);
298                                                         val = (snd_p->sample[1] >> 8) + 128;*snd_out++ = bound(0, val, 255);
299                                                 }
300                                         }
301                                 }
302                                 else if (shm->format.channels == 1)
303                                 {
304                                         // 1.0 mono
305                                         for (i = 0;i < snd_frames;i++, snd_p++)
306                                         {
307                                                 val = ((snd_p->sample[0]+snd_p->sample[1]) >> 9) + 128;*snd_out++ = bound(0, val, 255);
308                                         }
309                                 }
310                         }
311                 }
312                 S_UnlockBuffer();
313         }
314 }
315
316
317 /*
318 ===============================================================================
319
320 CHANNEL MIXING
321
322 ===============================================================================
323 */
324
325 qboolean SND_PaintChannel (channel_t *ch, int endtime);
326
327 void S_PaintChannels(int endtime)
328 {
329         unsigned int i, j;
330         int end;
331         channel_t *ch;
332         sfx_t *sfx;
333         int ltime, count;
334
335         while (paintedtime < endtime)
336         {
337                 // if paintbuffer is smaller than DMA buffer
338                 end = endtime;
339                 if (endtime - paintedtime > PAINTBUFFER_SIZE)
340                         end = paintedtime + PAINTBUFFER_SIZE;
341
342                 // clear the paint buffer
343                 memset (&paintbuffer, 0, (end - paintedtime) * sizeof (paintbuffer[0]));
344
345                 // paint in the channels.
346                 ch = channels;
347                 for (i=0; i<total_channels ; i++, ch++)
348                 {
349                         sfx = ch->sfx;
350                         if (!sfx)
351                                 continue;
352                         for (j = 0;j < SND_LISTENERS;j++)
353                                 if (ch->listener_volume[j])
354                                         break;
355                         if (j == SND_LISTENERS)
356                                 continue;
357                         if (!S_LoadSound (sfx, true))
358                                 continue;
359
360                         // if the channel is paused
361                         if (ch->flags & CHANNELFLAG_PAUSED)
362                         {
363                                 int pausedtime = end - paintedtime;
364                                 ch->lastptime += pausedtime;
365                                 ch->end += pausedtime;
366                                 continue;
367                         }
368
369                         // if the sound hasn't been painted last time, update his position
370                         if (ch->lastptime < paintedtime)
371                         {
372                                 ch->pos += paintedtime - ch->lastptime;
373
374                                 // If the sound should have ended by then
375                                 if ((unsigned int)ch->pos > sfx->total_length)
376                                 {
377                                         int loopstart;
378
379                                         if (ch->flags & CHANNELFLAG_FORCELOOP)
380                                                 loopstart = 0;
381                                         else
382                                                 loopstart = -1;
383                                         if (sfx->loopstart >= 0)
384                                                 loopstart = sfx->loopstart;
385
386                                         // If the sound is looped
387                                         if (loopstart >= 0)
388                                                 ch->pos = (ch->pos - sfx->total_length) % (sfx->total_length - loopstart) + loopstart;
389                                         else
390                                                 ch->pos = sfx->total_length;
391                                         ch->end = paintedtime + sfx->total_length - ch->pos;
392                                 }
393                         }
394
395                         ltime = paintedtime;
396                         while (ltime < end)
397                         {
398                                 qboolean stop_paint;
399
400                                 // paint up to end
401                                 if (ch->end < end)
402                                         count = (int)ch->end - ltime;
403                                 else
404                                         count = end - ltime;
405
406                                 if (count > 0)
407                                 {
408                                         for (j = 0;j < SND_LISTENERS;j++)
409                                                 ch->listener_volume[j] = bound(0, ch->listener_volume[j], 255);
410
411                                         stop_paint = !SND_PaintChannel (ch, count);
412
413                                         if (!stop_paint)
414                                         {
415                                                 ltime += count;
416                                                 ch->lastptime = ltime;
417                                         }
418                                 }
419                                 else
420                                         stop_paint = false;
421
422                                 if (ltime >= ch->end)
423                                 {
424                                         // if at end of loop, restart
425                                         if ((sfx->loopstart >= 0 || (ch->flags & CHANNELFLAG_FORCELOOP)) && !stop_paint)
426                                         {
427                                                 ch->pos = bound(0, sfx->loopstart, (int)sfx->total_length - 1);
428                                                 ch->end = ltime + sfx->total_length - ch->pos;
429                                         }
430                                         // channel just stopped
431                                         else
432                                                 stop_paint = true;
433                                 }
434
435                                 if (stop_paint)
436                                 {
437                                         S_StopChannel (ch - channels);
438                                         break;
439                                 }
440                         }
441                 }
442
443                 // transfer out according to DMA format
444                 S_CaptureAVISound (paintbuffer, end - paintedtime);
445                 S_TransferPaintBuffer(end);
446                 paintedtime = end;
447         }
448 }
449
450
451 qboolean SND_PaintChannel (channel_t *ch, int count)
452 {
453         int snd_vol, vol[SND_LISTENERS];
454         const sfxbuffer_t *sb;
455         int i;
456
457         // If this channel manages its own volume
458         if (ch->flags & CHANNELFLAG_FULLVOLUME)
459                 snd_vol = 256;
460         else
461                 snd_vol = volume.value * 256;
462
463         for (i = 0;i < SND_LISTENERS;i++)
464                 vol[i] = ch->listener_volume[i] * snd_vol;
465
466         sb = ch->sfx->fetcher->getsb (ch, ch->pos, count);
467         if (sb == NULL)
468                 return false;
469
470 #if SND_LISTENERS != 8
471 #error this code only supports up to 8 channels, update it
472 #endif
473
474         if (ch->sfx->format.width == 1)
475         {
476                 const signed char *sfx = (signed char *)sb->data + (ch->pos - sb->offset) * ch->sfx->format.channels;
477                 // Stereo sound support
478                 if (ch->sfx->format.channels == 2)
479                 {
480                         if (vol[6] + vol[7] > 0)
481                         {
482                                 for (i = 0;i < count;i++)
483                                 {
484                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 8;
485                                         paintbuffer[i].sample[1] += (sfx[1] * vol[1]) >> 8;
486                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 8;
487                                         paintbuffer[i].sample[3] += (sfx[1] * vol[3]) >> 8;
488                                         paintbuffer[i].sample[4] += ((sfx[0]+sfx[1]) * vol[4]) >> 9;
489                                         paintbuffer[i].sample[5] += ((sfx[0]+sfx[1]) * vol[5]) >> 9;
490                                         paintbuffer[i].sample[6] += (sfx[0] * vol[6]) >> 8;
491                                         paintbuffer[i].sample[7] += (sfx[1] * vol[7]) >> 8;
492                                         sfx += 2;
493                                 }
494                         }
495                         else if (vol[4] + vol[5] > 0)
496                         {
497                                 for (i = 0;i < count;i++)
498                                 {
499                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 8;
500                                         paintbuffer[i].sample[1] += (sfx[1] * vol[1]) >> 8;
501                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 8;
502                                         paintbuffer[i].sample[3] += (sfx[1] * vol[3]) >> 8;
503                                         paintbuffer[i].sample[4] += ((sfx[0]+sfx[1]) * vol[4]) >> 9;
504                                         paintbuffer[i].sample[5] += ((sfx[0]+sfx[1]) * vol[5]) >> 9;
505                                         sfx += 2;
506                                 }
507                         }
508                         else if (vol[2] + vol[3] > 0)
509                         {
510                                 for (i = 0;i < count;i++)
511                                 {
512                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 8;
513                                         paintbuffer[i].sample[1] += (sfx[1] * vol[1]) >> 8;
514                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 8;
515                                         paintbuffer[i].sample[3] += (sfx[1] * vol[3]) >> 8;
516                                         sfx += 2;
517                                 }
518                         }
519                         else if (vol[0] + vol[1] > 0)
520                         {
521                                 for (i = 0;i < count;i++)
522                                 {
523                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 8;
524                                         paintbuffer[i].sample[1] += (sfx[1] * vol[1]) >> 8;
525                                         sfx += 2;
526                                 }
527                         }
528                 }
529                 else if (ch->sfx->format.channels == 1)
530                 {
531                         if (vol[6] + vol[7] > 0)
532                         {
533                                 for (i = 0;i < count;i++)
534                                 {
535                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 8;
536                                         paintbuffer[i].sample[1] += (sfx[0] * vol[1]) >> 8;
537                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 8;
538                                         paintbuffer[i].sample[3] += (sfx[0] * vol[3]) >> 8;
539                                         paintbuffer[i].sample[4] += (sfx[0] * vol[4]) >> 8;
540                                         paintbuffer[i].sample[5] += (sfx[0] * vol[5]) >> 8;
541                                         paintbuffer[i].sample[6] += (sfx[0] * vol[6]) >> 8;
542                                         paintbuffer[i].sample[7] += (sfx[0] * vol[7]) >> 8;
543                                         sfx += 1;
544                                 }
545                         }
546                         else if (vol[4] + vol[5] > 0)
547                         {
548                                 for (i = 0;i < count;i++)
549                                 {
550                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 8;
551                                         paintbuffer[i].sample[1] += (sfx[0] * vol[1]) >> 8;
552                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 8;
553                                         paintbuffer[i].sample[3] += (sfx[0] * vol[3]) >> 8;
554                                         paintbuffer[i].sample[4] += (sfx[0] * vol[4]) >> 8;
555                                         paintbuffer[i].sample[5] += (sfx[0] * vol[5]) >> 8;
556                                         sfx += 1;
557                                 }
558                         }
559                         else if (vol[2] + vol[3] > 0)
560                         {
561                                 for (i = 0;i < count;i++)
562                                 {
563                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 8;
564                                         paintbuffer[i].sample[1] += (sfx[0] * vol[1]) >> 8;
565                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 8;
566                                         paintbuffer[i].sample[3] += (sfx[0] * vol[3]) >> 8;
567                                         sfx += 1;
568                                 }
569                         }
570                         else if (vol[0] + vol[1] > 0)
571                         {
572                                 for (i = 0;i < count;i++)
573                                 {
574                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 8;
575                                         paintbuffer[i].sample[1] += (sfx[0] * vol[1]) >> 8;
576                                         sfx += 1;
577                                 }
578                         }
579                 }
580                 else
581                         return true; // unsupported number of channels in sound
582         }
583         else if (ch->sfx->format.width == 2)
584         {
585                 const signed short *sfx = (signed short *)sb->data + (ch->pos - sb->offset) * ch->sfx->format.channels;
586                 // Stereo sound support
587                 if (ch->sfx->format.channels == 2)
588                 {
589                         if (vol[6] + vol[7] > 0)
590                         {
591                                 for (i = 0;i < count;i++)
592                                 {
593                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 16;
594                                         paintbuffer[i].sample[1] += (sfx[1] * vol[1]) >> 16;
595                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 16;
596                                         paintbuffer[i].sample[3] += (sfx[1] * vol[3]) >> 16;
597                                         paintbuffer[i].sample[4] += ((sfx[0]+sfx[1]) * vol[4]) >> 17;
598                                         paintbuffer[i].sample[5] += ((sfx[0]+sfx[1]) * vol[5]) >> 17;
599                                         paintbuffer[i].sample[6] += (sfx[0] * vol[6]) >> 16;
600                                         paintbuffer[i].sample[7] += (sfx[1] * vol[7]) >> 16;
601                                         sfx += 2;
602                                 }
603                         }
604                         else if (vol[4] + vol[5] > 0)
605                         {
606                                 for (i = 0;i < count;i++)
607                                 {
608                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 16;
609                                         paintbuffer[i].sample[1] += (sfx[1] * vol[1]) >> 16;
610                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 16;
611                                         paintbuffer[i].sample[3] += (sfx[1] * vol[3]) >> 16;
612                                         paintbuffer[i].sample[4] += ((sfx[0]+sfx[1]) * vol[4]) >> 17;
613                                         paintbuffer[i].sample[5] += ((sfx[0]+sfx[1]) * vol[5]) >> 17;
614                                         sfx += 2;
615                                 }
616                         }
617                         else if (vol[2] + vol[3] > 0)
618                         {
619                                 for (i = 0;i < count;i++)
620                                 {
621                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 16;
622                                         paintbuffer[i].sample[1] += (sfx[1] * vol[1]) >> 16;
623                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 16;
624                                         paintbuffer[i].sample[3] += (sfx[1] * vol[3]) >> 16;
625                                         sfx += 2;
626                                 }
627                         }
628                         else if (vol[0] + vol[1] > 0)
629                         {
630                                 for (i = 0;i < count;i++)
631                                 {
632                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 16;
633                                         paintbuffer[i].sample[1] += (sfx[1] * vol[1]) >> 16;
634                                         sfx += 2;
635                                 }
636                         }
637                 }
638                 else if (ch->sfx->format.channels == 1)
639                 {
640                         if (vol[6] + vol[7] > 0)
641                         {
642                                 for (i = 0;i < count;i++)
643                                 {
644                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 16;
645                                         paintbuffer[i].sample[1] += (sfx[0] * vol[1]) >> 16;
646                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 16;
647                                         paintbuffer[i].sample[3] += (sfx[0] * vol[3]) >> 16;
648                                         paintbuffer[i].sample[4] += (sfx[0] * vol[4]) >> 16;
649                                         paintbuffer[i].sample[5] += (sfx[0] * vol[5]) >> 16;
650                                         paintbuffer[i].sample[6] += (sfx[0] * vol[6]) >> 16;
651                                         paintbuffer[i].sample[7] += (sfx[0] * vol[7]) >> 16;
652                                         sfx += 1;
653                                 }
654                         }
655                         else if (vol[4] + vol[5] > 0)
656                         {
657                                 for (i = 0;i < count;i++)
658                                 {
659                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 16;
660                                         paintbuffer[i].sample[1] += (sfx[0] * vol[1]) >> 16;
661                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 16;
662                                         paintbuffer[i].sample[3] += (sfx[0] * vol[3]) >> 16;
663                                         paintbuffer[i].sample[4] += (sfx[0] * vol[4]) >> 16;
664                                         paintbuffer[i].sample[5] += (sfx[0] * vol[5]) >> 16;
665                                         sfx += 1;
666                                 }
667                         }
668                         else if (vol[2] + vol[3] > 0)
669                         {
670                                 for (i = 0;i < count;i++)
671                                 {
672                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 16;
673                                         paintbuffer[i].sample[1] += (sfx[0] * vol[1]) >> 16;
674                                         paintbuffer[i].sample[2] += (sfx[0] * vol[2]) >> 16;
675                                         paintbuffer[i].sample[3] += (sfx[0] * vol[3]) >> 16;
676                                         sfx += 1;
677                                 }
678                         }
679                         else if (vol[0] + vol[1] > 0)
680                         {
681                                 for (i = 0;i < count;i++)
682                                 {
683                                         paintbuffer[i].sample[0] += (sfx[0] * vol[0]) >> 16;
684                                         paintbuffer[i].sample[1] += (sfx[0] * vol[1]) >> 16;
685                                         sfx += 1;
686                                 }
687                         }
688                 }
689                 else
690                         return true; // unsupported number of channels in sound
691         }
692         ch->pos += count;
693         return true;
694 }
695