From 4f8c7c2f2f2ea979518d2e116e48838df45e7ea6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 13 Apr 2018 14:05:12 -0400 Subject: [PATCH] Support SDL audio devices that require float32 samples. Fixes missing audio when playing on Windows with SDL 2.0.7, which started using WASAPI, which demands floating point audio. --- code/client/cl_avi.c | 3 +++ code/client/snd_dma.c | 2 +- code/client/snd_local.h | 1 + code/client/snd_mix.c | 17 ++++++++++++++++- code/sdl/sdl_snd.c | 7 +++++-- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/code/client/cl_avi.c b/code/client/cl_avi.c index 17fd371f..2f0dffd6 100644 --- a/code/client/cl_avi.c +++ b/code/client/cl_avi.c @@ -368,6 +368,9 @@ qboolean CL_OpenAVIForWriting( const char *fileName ) afd.a.rate = dma.speed; afd.a.format = WAV_FORMAT_PCM; afd.a.channels = dma.channels; + /* !!! FIXME: if CL_WriteAVIAudioFrame() is ever called from somewhere other + !!! FIXME: than S_TransferStereo16(), we will need to handle/convert + !!! FIXME: float32 samples for AVI writing. */ afd.a.bits = dma.samplebits; afd.a.sampleSize = ( afd.a.bits / 8 ) * afd.a.channels; diff --git a/code/client/snd_dma.c b/code/client/snd_dma.c index 2078b811..382031b6 100644 --- a/code/client/snd_dma.c +++ b/code/client/snd_dma.c @@ -100,7 +100,7 @@ void S_Base_SoundInfo(void) { } else { Com_Printf("%5d stereo\n", dma.channels - 1); Com_Printf("%5d samples\n", dma.samples); - Com_Printf("%5d samplebits\n", dma.samplebits); + Com_Printf("%5d samplebits (%s)\n", dma.samplebits, dma.isfloat ? "float" : "int"); Com_Printf("%5d submission_chunk\n", dma.submission_chunk); Com_Printf("%5d speed\n", dma.speed); Com_Printf("%p dma buffer\n", dma.buffer); diff --git a/code/client/snd_local.h b/code/client/snd_local.h index e0f5b1d0..053325cf 100644 --- a/code/client/snd_local.h +++ b/code/client/snd_local.h @@ -67,6 +67,7 @@ typedef struct { int samples; // mono samples in buffer int submission_chunk; // don't mix less than this # int samplebits; + int isfloat; int speed; byte *buffer; } dma_t; diff --git a/code/client/snd_mix.c b/code/client/snd_mix.c index 53230812..99fe03c5 100644 --- a/code/client/snd_mix.c +++ b/code/client/snd_mix.c @@ -184,7 +184,22 @@ void S_TransferPaintBuffer(int endtime) out_idx = s_paintedtime * dma.channels & out_mask; step = 3 - dma.channels; - if (dma.samplebits == 16) + if ((dma.isfloat) && (dma.samplebits == 32)) + { + float *out = (float *) pbuf; + while (count--) + { + val = *p >> 8; + p+= step; + if (val > 0x7fff) + val = 0x7fff; + else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */ + val = -32767; + out[out_idx] = ((float) val) / 32767.0f; + out_idx = (out_idx + 1) & out_mask; + } + } + else if (dma.samplebits == 16) { short *out = (short *) pbuf; while (count--) diff --git a/code/sdl/sdl_snd.c b/code/sdl/sdl_snd.c index 609aed9e..2be64e1d 100644 --- a/code/sdl/sdl_snd.c +++ b/code/sdl/sdl_snd.c @@ -96,7 +96,9 @@ static struct { AUDIO_U16LSB, "AUDIO_U16LSB" }, { AUDIO_S16LSB, "AUDIO_S16LSB" }, { AUDIO_U16MSB, "AUDIO_U16MSB" }, - { AUDIO_S16MSB, "AUDIO_S16MSB" } + { AUDIO_S16MSB, "AUDIO_S16MSB" }, + { AUDIO_F32LSB, "AUDIO_F32LSB" }, + { AUDIO_F32MSB, "AUDIO_F32MSB" } }; static int formatToStringTableSize = ARRAY_LEN( formatToStringTable ); @@ -228,7 +230,8 @@ qboolean SNDDMA_Init(void) } dmapos = 0; - dma.samplebits = obtained.format & 0xFF; // first byte of format is bits. + dma.samplebits = SDL_AUDIO_BITSIZE(obtained.format); + dma.isfloat = SDL_AUDIO_ISFLOAT(obtained.format); dma.channels = obtained.channels; dma.samples = tmp; dma.submission_chunk = 1;