Fix SDL audio playback with surround sound

If user has surround sound enabled, ioq3 would not play any sound.
Fix painting sound buffer for 4/5.1 audio channels. Extra channels
currently play no audio.
This commit is contained in:
Zack Middleton 2018-09-13 12:45:37 -05:00
parent e4208cf5a7
commit 812a3dbfa5
3 changed files with 39 additions and 27 deletions

View file

@ -1339,7 +1339,7 @@ void S_Update_(void) {
& ~(dma.submission_chunk-1); & ~(dma.submission_chunk-1);
// never mix more than the complete buffer // never mix more than the complete buffer
samps = dma.samples >> (dma.channels-1); samps = dma.samples / dma.channels;
if (endtime - s_soundtime > samps) if (endtime - s_soundtime > samps)
endtime = s_soundtime + samps; endtime = s_soundtime + samps;

View file

@ -150,18 +150,16 @@ void S_TransferPaintBuffer(int endtime)
{ {
int out_idx; int out_idx;
int count; int count;
int out_mask;
int *p; int *p;
int step; int step;
int val; int val;
int i;
unsigned long *pbuf; unsigned long *pbuf;
pbuf = (unsigned long *)dma.buffer; pbuf = (unsigned long *)dma.buffer;
if ( s_testsound->integer ) { if ( s_testsound->integer ) {
int i;
// write a fixed sine wave // write a fixed sine wave
count = (endtime - s_paintedtime); count = (endtime - s_paintedtime);
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
@ -177,53 +175,73 @@ void S_TransferPaintBuffer(int endtime)
{ // general case { // general case
p = (int *) paintbuffer; p = (int *) paintbuffer;
count = (endtime - s_paintedtime) * dma.channels; count = (endtime - s_paintedtime) * dma.channels;
out_mask = dma.samples - 1; out_idx = s_paintedtime * dma.channels % dma.samples;
out_idx = s_paintedtime * dma.channels & out_mask; step = 3 - MIN( dma.channels, 2 );
step = 3 - dma.channels;
if ((dma.isfloat) && (dma.samplebits == 32)) if ((dma.isfloat) && (dma.samplebits == 32))
{ {
float *out = (float *) pbuf; float *out = (float *) pbuf;
while (count--) for (i=0 ; i<count ; i++)
{
if ( i % dma.channels >= 2 )
{
val = 0;
}
else
{ {
val = *p >> 8; val = *p >> 8;
p+= step; p+= step;
}
if (val > 0x7fff) if (val > 0x7fff)
val = 0x7fff; val = 0x7fff;
else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */ else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */
val = -32767; val = -32767;
out[out_idx] = ((float) val) / 32767.0f; out[out_idx] = ((float) val) / 32767.0f;
out_idx = (out_idx + 1) & out_mask; out_idx = (out_idx + 1) % dma.samples;
} }
} }
else if (dma.samplebits == 16) else if (dma.samplebits == 16)
{ {
short *out = (short *) pbuf; short *out = (short *) pbuf;
while (count--) for (i=0 ; i<count ; i++)
{
if ( i % dma.channels >= 2 )
{
val = 0;
}
else
{ {
val = *p >> 8; val = *p >> 8;
p+= step; p+= step;
}
if (val > 0x7fff) if (val > 0x7fff)
val = 0x7fff; val = 0x7fff;
else if (val < -32768) else if (val < -32768)
val = -32768; val = -32768;
out[out_idx] = val; out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask; out_idx = (out_idx + 1) % dma.samples;
} }
} }
else if (dma.samplebits == 8) else if (dma.samplebits == 8)
{ {
unsigned char *out = (unsigned char *) pbuf; unsigned char *out = (unsigned char *) pbuf;
while (count--) for (i=0 ; i<count ; i++)
{
if ( i % dma.channels >= 2 )
{
val = 0;
}
else
{ {
val = *p >> 8; val = *p >> 8;
p+= step; p+= step;
}
if (val > 0x7fff) if (val > 0x7fff)
val = 0x7fff; val = 0x7fff;
else if (val < -32768) else if (val < -32768)
val = -32768; val = -32768;
out[out_idx] = (val>>8) + 128; out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask; out_idx = (out_idx + 1) % dma.samples;
} }
} }
} }

View file

@ -267,14 +267,8 @@ qboolean SNDDMA_Init(void)
if (!tmp) if (!tmp)
tmp = (obtained.samples * obtained.channels) * 10; tmp = (obtained.samples * obtained.channels) * 10;
if (tmp & (tmp - 1)) // not a power of two? Seems to confuse something. // samples must be divisible by number of channels
{ tmp -= tmp % obtained.channels;
int val = 1;
while (val < tmp)
val <<= 1;
tmp = val;
}
dmapos = 0; dmapos = 0;
dma.samplebits = SDL_AUDIO_BITSIZE(obtained.format); dma.samplebits = SDL_AUDIO_BITSIZE(obtained.format);