icculus quake2 doxygen  1.0 dev
snd_mix.c File Reference
#include "client.h"
#include "snd_loc.h"

Go to the source code of this file.

Macros

#define PAINTBUFFER_SIZE   2048
 

Functions

void S_WriteLinearBlastStereo16 (void)
 
void S_TransferStereo16 (unsigned long *pbuf, int endtime)
 
void S_TransferPaintBuffer (int endtime)
 
void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime, int offset)
 
void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime, int offset)
 
void S_PaintChannels (int endtime)
 
void S_InitScaletable (void)
 

Variables

portable_samplepair_t paintbuffer [PAINTBUFFER_SIZE]
 
int snd_scaletable [32][256]
 
intsnd_p
 
int snd_linear_count
 
int snd_vol
 
short * snd_out
 

Macro Definition Documentation

◆ PAINTBUFFER_SIZE

#define PAINTBUFFER_SIZE   2048

Definition at line 25 of file snd_mix.c.

Function Documentation

◆ S_InitScaletable()

void S_InitScaletable ( void  )

Definition at line 350 of file snd_mix.c.

351 {
352  int i, j;
353  int scale;
354 
355  s_volume->modified = false;
356  for (i=0 ; i<32 ; i++)
357  {
358  scale = i * 8 * 256 * s_volume->value;
359  for (j=0 ; j<256 ; j++)
360  snd_scaletable[i][j] = ((signed char)j) * scale;
361  }
362 }

Referenced by S_Init(), and S_Update().

◆ S_PaintChannelFrom16()

void S_PaintChannelFrom16 ( channel_t ch,
sfxcache_t sc,
int  endtime,
int  offset 
)

Definition at line 474 of file snd_mix.c.

475 {
476  int data;
477  int left, right;
478  int leftvol, rightvol;
479  signed short *sfx;
480  int i;
481  portable_samplepair_t *samp;
482 
483  leftvol = ch->leftvol*snd_vol;
484  rightvol = ch->rightvol*snd_vol;
485  sfx = (signed short *)sc->data + ch->pos;
486 
487  samp = &paintbuffer[offset];
488  for (i=0 ; i<count ; i++, samp++)
489  {
490  data = sfx[i];
491  left = (data * leftvol)>>8;
492  right = (data * rightvol)>>8;
493  samp->left += left;
494  samp->right += right;
495  }
496 
497  ch->pos += count;
498 }

Referenced by S_PaintChannels().

◆ S_PaintChannelFrom8()

void S_PaintChannelFrom8 ( channel_t ch,
sfxcache_t sc,
int  endtime,
int  offset 
)

Definition at line 368 of file snd_mix.c.

369 {
370  int data;
371  int *lscale, *rscale;
372  unsigned char *sfx;
373  int i;
374  portable_samplepair_t *samp;
375 
376  if (ch->leftvol > 255)
377  ch->leftvol = 255;
378  if (ch->rightvol > 255)
379  ch->rightvol = 255;
380 
381  //ZOID-- >>11 has been changed to >>3, >>11 didn't make much sense
382  //as it would always be zero.
383  lscale = snd_scaletable[ ch->leftvol >> 3];
384  rscale = snd_scaletable[ ch->rightvol >> 3];
385  sfx = (signed char *)sc->data + ch->pos;
386 
387  samp = &paintbuffer[offset];
388 
389  for (i=0 ; i<count ; i++, samp++)
390  {
391  data = sfx[i];
392  samp->left += lscale[data];
393  samp->right += rscale[data];
394  }
395 
396  ch->pos += count;
397 }

Referenced by S_PaintChannels().

◆ S_PaintChannels()

void S_PaintChannels ( int  endtime)

Definition at line 224 of file snd_mix.c.

225 {
226  int i;
227  int end;
228  channel_t *ch;
229  sfxcache_t *sc;
230  int ltime, count;
231  playsound_t *ps;
232 
233  snd_vol = s_volume->value*256;
234 
235 //Com_Printf ("%i to %i\n", paintedtime, endtime);
236  while (paintedtime < endtime)
237  {
238  // if paintbuffer is smaller than DMA buffer
239  end = endtime;
240  if (endtime - paintedtime > PAINTBUFFER_SIZE)
242 
243  // start any playsounds
244  while (1)
245  {
246  ps = s_pendingplays.next;
247  if (ps == &s_pendingplays)
248  break; // no more pending sounds
249  if (ps->begin <= paintedtime)
250  {
251  S_IssuePlaysound (ps);
252  continue;
253  }
254 
255  if (ps->begin < end)
256  end = ps->begin; // stop here
257  break;
258  }
259 
260  // clear the paint buffer
261  if (s_rawend < paintedtime)
262  {
263 // Com_Printf ("clear\n");
264  memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
265  }
266  else
267  { // copy from the streaming sound source
268  int s;
269  int stop;
270 
271  stop = (end < s_rawend) ? end : s_rawend;
272 
273  for (i=paintedtime ; i<stop ; i++)
274  {
275  s = i&(MAX_RAW_SAMPLES-1);
277  }
278 // if (i != end)
279 // Com_Printf ("partial stream\n");
280 // else
281 // Com_Printf ("full stream\n");
282  for ( ; i<end ; i++)
283  {
286  }
287  }
288 
289 
290  // paint in the channels.
291  ch = channels;
292  for (i=0; i<MAX_CHANNELS ; i++, ch++)
293  {
294  ltime = paintedtime;
295 
296  while (ltime < end)
297  {
298  if (!ch->sfx || (!ch->leftvol && !ch->rightvol) )
299  break;
300 
301  // max painting is to the end of the buffer
302  count = end - ltime;
303 
304  // might be stopped by running out of data
305  if (ch->end - ltime < count)
306  count = ch->end - ltime;
307 
308  sc = S_LoadSound (ch->sfx);
309  if (!sc)
310  break;
311 
312  if (count > 0 && ch->sfx)
313  {
314  if (sc->width == 1)// FIXME; 8 bit asm is wrong now
315  S_PaintChannelFrom8(ch, sc, count, ltime - paintedtime);
316  else
317  S_PaintChannelFrom16(ch, sc, count, ltime - paintedtime);
318 
319  ltime += count;
320  }
321 
322  // if at end of loop, restart
323  if (ltime >= ch->end)
324  {
325  if (ch->autosound)
326  { // autolooping sounds always go back to start
327  ch->pos = 0;
328  ch->end = ltime + sc->length;
329  }
330  else if (sc->loopstart >= 0)
331  {
332  ch->pos = sc->loopstart;
333  ch->end = ltime + sc->length - ch->pos;
334  }
335  else
336  { // channel just stopped
337  ch->sfx = NULL;
338  }
339  }
340  }
341 
342  }
343 
344  // transfer out according to DMA format
346  paintedtime = end;
347  }
348 }

Referenced by S_Update_().

◆ S_TransferPaintBuffer()

void S_TransferPaintBuffer ( int  endtime)

Definition at line 143 of file snd_mix.c.

144 {
145  int out_idx;
146  int count;
147  int out_mask;
148  int *p;
149  int step;
150  int val;
151  unsigned long *pbuf;
152 
153  pbuf = (unsigned long *)dma.buffer;
154 
155  if (s_testsound->value)
156  {
157  int i;
158  int count;
159 
160  // write a fixed sine wave
161  count = (endtime - paintedtime);
162  for (i=0 ; i<count ; i++)
163  paintbuffer[i].left = paintbuffer[i].right = sin((paintedtime+i)*0.1)*20000*256;
164  }
165 
166 
167  if (dma.samplebits == 16 && dma.channels == 2)
168  { // optimized case
169  S_TransferStereo16 (pbuf, endtime);
170  }
171  else
172  { // general case
173  p = (int *) paintbuffer;
174  count = (endtime - paintedtime) * dma.channels;
175  out_mask = dma.samples - 1;
176  out_idx = paintedtime * dma.channels & out_mask;
177  step = 3 - dma.channels;
178 
179  if (dma.samplebits == 16)
180  {
181  short *out = (short *) pbuf;
182  while (count--)
183  {
184  val = *p >> 8;
185  p+= step;
186  if (val > 0x7fff)
187  val = 0x7fff;
188  else if (val < (short)0x8000)
189  val = (short)0x8000;
190  out[out_idx] = val;
191  out_idx = (out_idx + 1) & out_mask;
192  }
193  }
194  else if (dma.samplebits == 8)
195  {
196  unsigned char *out = (unsigned char *) pbuf;
197  while (count--)
198  {
199  val = *p >> 8;
200  p+= step;
201  if (val > 0x7fff)
202  val = 0x7fff;
203  else if (val < (short)0x8000)
204  val = (short)0x8000;
205  out[out_idx] = (val>>8) + 128;
206  out_idx = (out_idx + 1) & out_mask;
207  }
208  }
209  }
210 }

Referenced by S_PaintChannels().

◆ S_TransferStereo16()

void S_TransferStereo16 ( unsigned long *  pbuf,
int  endtime 
)

Definition at line 108 of file snd_mix.c.

109 {
110  int lpos;
111  int lpaintedtime;
112 
113  snd_p = (int *) paintbuffer;
114  lpaintedtime = paintedtime;
115 
116  while (lpaintedtime < endtime)
117  {
118  // handle recirculating buffer issues
119  lpos = lpaintedtime & ((dma.samples>>1)-1);
120 
121  snd_out = (short *) pbuf + (lpos<<1);
122 
123  snd_linear_count = (dma.samples>>1) - lpos;
124  if (lpaintedtime + snd_linear_count > endtime)
125  snd_linear_count = endtime - lpaintedtime;
126 
127  snd_linear_count <<= 1;
128 
129  // write a linear blast of samples
131 
133  lpaintedtime += (snd_linear_count>>1);
134  }
135 }

Referenced by S_TransferPaintBuffer().

◆ S_WriteLinearBlastStereo16()

void S_WriteLinearBlastStereo16 ( void  )

Definition at line 36 of file snd_mix.c.

37 {
38  int i;
39  int val;
40 
41  for (i=0 ; i<snd_linear_count ; i+=2)
42  {
43  val = snd_p[i]>>8;
44  if (val > 0x7fff)
45  snd_out[i] = 0x7fff;
46  else if (val < (short)0x8000)
47  snd_out[i] = (short)0x8000;
48  else
49  snd_out[i] = val;
50 
51  val = snd_p[i+1]>>8;
52  if (val > 0x7fff)
53  snd_out[i+1] = 0x7fff;
54  else if (val < (short)0x8000)
55  snd_out[i+1] = (short)0x8000;
56  else
57  snd_out[i+1] = val;
58  }
59 }

Referenced by S_TransferStereo16().

Variable Documentation

◆ paintbuffer

◆ snd_linear_count

int snd_linear_count

Definition at line 28 of file snd_mix.c.

Referenced by S_TransferStereo16(), and S_WriteLinearBlastStereo16().

◆ snd_out

short* snd_out

Definition at line 29 of file snd_mix.c.

Referenced by S_TransferStereo16(), and S_WriteLinearBlastStereo16().

◆ snd_p

int* snd_p

Definition at line 28 of file snd_mix.c.

Referenced by S_TransferStereo16(), and S_WriteLinearBlastStereo16().

◆ snd_scaletable

int snd_scaletable[32][256]

Definition at line 27 of file snd_mix.c.

Referenced by S_InitScaletable(), and S_PaintChannelFrom8().

◆ snd_vol

int snd_vol

Definition at line 28 of file snd_mix.c.

Referenced by S_PaintChannelFrom16(), and S_PaintChannels().

MAX_CHANNELS
#define MAX_CHANNELS
Definition: snd_loc.h:126
s_testsound
cvar_t * s_testsound
Definition: snd_dma.c:75
channel_t::pos
int pos
Definition: snd_loc.h:81
S_PaintChannelFrom8
void S_PaintChannelFrom8(channel_t *ch, sfxcache_t *sc, int endtime, int offset)
Definition: snd_mix.c:368
sfxcache_t::length
int length
Definition: snd_loc.h:31
channel_t::sfx
sfx_t * sfx
Definition: snd_loc.h:77
PAINTBUFFER_SIZE
#define PAINTBUFFER_SIZE
Definition: snd_mix.c:25
playsound_s
Definition: snd_loc.h:50
channel_t::autosound
qboolean autosound
Definition: snd_loc.h:89
s_rawend
int s_rawend
Definition: snd_dma.c:83
cvar_s::modified
qboolean modified
Definition: q_shared.h:323
channel_t::rightvol
int rightvol
Definition: snd_loc.h:79
i
int i
Definition: q_shared.c:305
channel_t::leftvol
int leftvol
Definition: snd_loc.h:78
dma_t::samples
int samples
Definition: snd_loc.h:66
portable_samplepair_t::left
int left
Definition: snd_loc.h:25
s_volume
cvar_t * s_volume
Definition: snd_dma.c:74
snd_p
int * snd_p
Definition: snd_mix.c:28
j
GLint j
Definition: qgl_win.c:150
playsound_s::begin
unsigned begin
Definition: snd_loc.h:60
MAX_RAW_SAMPLES
#define MAX_RAW_SAMPLES
Definition: snd_loc.h:138
S_LoadSound
sfxcache_t * S_LoadSound(sfx_t *s)
Definition: snd_mem.c:98
dma_t::buffer
byte * buffer
Definition: snd_loc.h:71
dma_t::channels
int channels
Definition: snd_loc.h:65
playsound_s::next
struct playsound_s * next
Definition: snd_loc.h:52
paintedtime
int paintedtime
Definition: snd_dma.c:57
snd_scaletable
int snd_scaletable[32][256]
Definition: snd_mix.c:27
S_TransferPaintBuffer
void S_TransferPaintBuffer(int endtime)
Definition: snd_mix.c:143
S_TransferStereo16
void S_TransferStereo16(unsigned long *pbuf, int endtime)
Definition: snd_mix.c:108
cvar_s::value
float value
Definition: q_shared.h:324
NULL
#define NULL
Definition: q_shared.h:60
dma
dma_t dma
Definition: snd_dma.c:47
channel_t
Definition: snd_loc.h:75
S_IssuePlaysound
void S_IssuePlaysound(playsound_t *ps)
Definition: snd_dma.c:550
channels
channel_t channels[MAX_CHANNELS]
Definition: snd_dma.c:42
s_rawsamples
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES]
Definition: snd_dma.c:84
snd_linear_count
int snd_linear_count
Definition: snd_mix.c:28
snd_vol
int snd_vol
Definition: snd_mix.c:28
paintbuffer
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE]
Definition: snd_mix.c:26
portable_samplepair_t::right
int right
Definition: snd_loc.h:26
portable_samplepair_t
Definition: snd_loc.h:23
s_pendingplays
playsound_t s_pendingplays
Definition: snd_dma.c:70
S_WriteLinearBlastStereo16
void S_WriteLinearBlastStereo16(void)
Definition: snd_mix.c:36
sfxcache_t
Definition: snd_loc.h:29
sfxcache_t::data
byte data[1]
Definition: snd_loc.h:36
sfxcache_t::width
int width
Definition: snd_loc.h:34
right
GLdouble right
Definition: qgl_win.c:159
dma_t::samplebits
int samplebits
Definition: snd_loc.h:69
snd_out
short * snd_out
Definition: snd_mix.c:29
channel_t::end
int end
Definition: snd_loc.h:80
sfxcache_t::loopstart
int loopstart
Definition: snd_loc.h:32
count
GLint GLsizei count
Definition: qgl_win.c:128
S_PaintChannelFrom16
void S_PaintChannelFrom16(channel_t *ch, sfxcache_t *sc, int endtime, int offset)
Definition: snd_mix.c:474