Fix SDL audio playback with 16-bit stereo sound

My commit last month "Fix SDL audio playback with surround sound" broke
16-bit stereo sound. S_TransferStereo16() still assumed that dma.samples
was a power of two. I also cleaned up code related to the previously
mentioned commit.
This commit is contained in:
Zack Middleton 2018-10-01 21:28:15 -05:00
parent 93dd14c9fb
commit 58b0fb07cd
4 changed files with 17 additions and 20 deletions

View file

@ -1242,9 +1242,6 @@ void S_GetSoundtime(void)
int samplepos; int samplepos;
static int buffers; static int buffers;
static int oldsamplepos; static int oldsamplepos;
int fullsamples;
fullsamples = dma.samples / dma.channels;
if( CL_VideoRecording( ) ) if( CL_VideoRecording( ) )
{ {
@ -1268,13 +1265,13 @@ void S_GetSoundtime(void)
if (s_paintedtime > 0x40000000) if (s_paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits { // time to chop things off to avoid 32 bit limits
buffers = 0; buffers = 0;
s_paintedtime = fullsamples; s_paintedtime = dma.fullsamples;
S_Base_StopAllSounds (); S_Base_StopAllSounds ();
} }
} }
oldsamplepos = samplepos; oldsamplepos = samplepos;
s_soundtime = buffers*fullsamples + samplepos/dma.channels; s_soundtime = buffers*dma.fullsamples + samplepos/dma.channels;
#if 0 #if 0
// check to make sure that we haven't overshot // check to make sure that we haven't overshot
@ -1295,7 +1292,6 @@ void S_GetSoundtime(void)
void S_Update_(void) { void S_Update_(void) {
unsigned endtime; unsigned endtime;
int samps;
static float lastTime = 0.0f; static float lastTime = 0.0f;
float ma, op; float ma, op;
float thisTime, sane; float thisTime, sane;
@ -1339,9 +1335,8 @@ 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; if (endtime - s_soundtime > dma.fullsamples)
if (endtime - s_soundtime > samps) endtime = s_soundtime + dma.fullsamples;
endtime = s_soundtime + samps;

View file

@ -65,6 +65,7 @@ typedef struct sfx_s {
typedef struct { typedef struct {
int channels; int channels;
int samples; // mono samples in buffer int samples; // mono samples in buffer
int fullsamples; // samples with all channels in buffer (samples divided by channels)
int submission_chunk; // don't mix less than this # int submission_chunk; // don't mix less than this #
int samplebits; int samplebits;
int isfloat; int isfloat;

View file

@ -119,24 +119,24 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime)
while (ls_paintedtime < endtime) while (ls_paintedtime < endtime)
{ {
// handle recirculating buffer issues // handle recirculating buffer issues
lpos = ls_paintedtime & ((dma.samples>>1)-1); lpos = ls_paintedtime % dma.fullsamples;
snd_out = (short *) pbuf + (lpos<<1); snd_out = (short *) pbuf + (lpos<<1); // lpos * dma.channels
snd_linear_count = (dma.samples>>1) - lpos; snd_linear_count = dma.fullsamples - lpos;
if (ls_paintedtime + snd_linear_count > endtime) if (ls_paintedtime + snd_linear_count > endtime)
snd_linear_count = endtime - ls_paintedtime; snd_linear_count = endtime - ls_paintedtime;
snd_linear_count <<= 1; snd_linear_count <<= 1; // snd_linear_count *= dma.channels
// write a linear blast of samples // write a linear blast of samples
S_WriteLinearBlastStereo16 (); S_WriteLinearBlastStereo16 ();
snd_p += snd_linear_count; snd_p += snd_linear_count;
ls_paintedtime += (snd_linear_count>>1); ls_paintedtime += (snd_linear_count>>1); // snd_linear_count / dma.channels
if( CL_VideoRecording( ) ) if( CL_VideoRecording( ) )
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); // snd_linear_count * (dma.samplebits/8)
} }
} }
@ -175,7 +175,7 @@ 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_idx = s_paintedtime * dma.channels % dma.samples; out_idx = (s_paintedtime * dma.channels) % dma.samples;
step = 3 - MIN(dma.channels, 2); step = 3 - MIN(dma.channels, 2);
if ((dma.isfloat) && (dma.samplebits == 32)) if ((dma.isfloat) && (dma.samplebits == 32))
@ -183,7 +183,7 @@ void S_TransferPaintBuffer(int endtime)
float *out = (float *) pbuf; float *out = (float *) pbuf;
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
{ {
if ( i % dma.channels >= 2 ) if ((i % dma.channels) >= 2)
{ {
val = 0; val = 0;
} }
@ -205,7 +205,7 @@ void S_TransferPaintBuffer(int endtime)
short *out = (short *) pbuf; short *out = (short *) pbuf;
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
{ {
if ( i % dma.channels >= 2 ) if ((i % dma.channels) >= 2)
{ {
val = 0; val = 0;
} }
@ -227,7 +227,7 @@ void S_TransferPaintBuffer(int endtime)
unsigned char *out = (unsigned char *) pbuf; unsigned char *out = (unsigned char *) pbuf;
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
{ {
if ( i % dma.channels >= 2 ) if ((i % dma.channels) >= 2)
{ {
val = 0; val = 0;
} }

View file

@ -272,6 +272,7 @@ qboolean SNDDMA_Init(void)
dma.isfloat = SDL_AUDIO_ISFLOAT(obtained.format); dma.isfloat = SDL_AUDIO_ISFLOAT(obtained.format);
dma.channels = obtained.channels; dma.channels = obtained.channels;
dma.samples = tmp; dma.samples = tmp;
dma.fullsamples = dma.samples / dma.channels;
dma.submission_chunk = 1; dma.submission_chunk = 1;
dma.speed = obtained.freq; dma.speed = obtained.freq;
dmasize = (dma.samples * (dma.samplebits/8)); dmasize = (dma.samples * (dma.samplebits/8));