From 58b0fb07cd61406bfce231c0d467d5b765ac7b30 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Mon, 1 Oct 2018 21:28:15 -0500 Subject: [PATCH] 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. --- code/client/snd_dma.c | 13 ++++--------- code/client/snd_local.h | 1 + code/client/snd_mix.c | 22 +++++++++++----------- code/sdl/sdl_snd.c | 1 + 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/code/client/snd_dma.c b/code/client/snd_dma.c index 3c33c78a..efa8a116 100644 --- a/code/client/snd_dma.c +++ b/code/client/snd_dma.c @@ -1242,9 +1242,6 @@ void S_GetSoundtime(void) int samplepos; static int buffers; static int oldsamplepos; - int fullsamples; - - fullsamples = dma.samples / dma.channels; if( CL_VideoRecording( ) ) { @@ -1268,13 +1265,13 @@ void S_GetSoundtime(void) if (s_paintedtime > 0x40000000) { // time to chop things off to avoid 32 bit limits buffers = 0; - s_paintedtime = fullsamples; + s_paintedtime = dma.fullsamples; S_Base_StopAllSounds (); } } oldsamplepos = samplepos; - s_soundtime = buffers*fullsamples + samplepos/dma.channels; + s_soundtime = buffers*dma.fullsamples + samplepos/dma.channels; #if 0 // check to make sure that we haven't overshot @@ -1295,7 +1292,6 @@ void S_GetSoundtime(void) void S_Update_(void) { unsigned endtime; - int samps; static float lastTime = 0.0f; float ma, op; float thisTime, sane; @@ -1339,9 +1335,8 @@ void S_Update_(void) { & ~(dma.submission_chunk-1); // never mix more than the complete buffer - samps = dma.samples / dma.channels; - if (endtime - s_soundtime > samps) - endtime = s_soundtime + samps; + if (endtime - s_soundtime > dma.fullsamples) + endtime = s_soundtime + dma.fullsamples; diff --git a/code/client/snd_local.h b/code/client/snd_local.h index 3b86d974..65392e36 100644 --- a/code/client/snd_local.h +++ b/code/client/snd_local.h @@ -65,6 +65,7 @@ typedef struct sfx_s { typedef struct { int channels; 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 samplebits; int isfloat; diff --git a/code/client/snd_mix.c b/code/client/snd_mix.c index d3b6d0d1..8923b7cb 100644 --- a/code/client/snd_mix.c +++ b/code/client/snd_mix.c @@ -119,24 +119,24 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime) while (ls_paintedtime < endtime) { // 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) 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 S_WriteLinearBlastStereo16 (); 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( ) ) - 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,15 +175,15 @@ void S_TransferPaintBuffer(int endtime) { // general case p = (int *) paintbuffer; count = (endtime - s_paintedtime) * dma.channels; - out_idx = s_paintedtime * dma.channels % dma.samples; - step = 3 - MIN( dma.channels, 2 ); + out_idx = (s_paintedtime * dma.channels) % dma.samples; + step = 3 - MIN(dma.channels, 2); if ((dma.isfloat) && (dma.samplebits == 32)) { float *out = (float *) pbuf; for (i=0 ; i= 2 ) + if ((i % dma.channels) >= 2) { val = 0; } @@ -205,7 +205,7 @@ void S_TransferPaintBuffer(int endtime) short *out = (short *) pbuf; for (i=0 ; i= 2 ) + if ((i % dma.channels) >= 2) { val = 0; } @@ -227,7 +227,7 @@ void S_TransferPaintBuffer(int endtime) unsigned char *out = (unsigned char *) pbuf; for (i=0 ; i= 2 ) + if ((i % dma.channels) >= 2) { val = 0; } diff --git a/code/sdl/sdl_snd.c b/code/sdl/sdl_snd.c index 3063ad2e..eb0dd58f 100644 --- a/code/sdl/sdl_snd.c +++ b/code/sdl/sdl_snd.c @@ -272,6 +272,7 @@ qboolean SNDDMA_Init(void) dma.isfloat = SDL_AUDIO_ISFLOAT(obtained.format); dma.channels = obtained.channels; dma.samples = tmp; + dma.fullsamples = dma.samples / dma.channels; dma.submission_chunk = 1; dma.speed = obtained.freq; dmasize = (dma.samples * (dma.samplebits/8));