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.
This commit is contained in:
Ryan C. Gordon 2018-04-13 14:05:12 -04:00
parent 3377f9981a
commit 4f8c7c2f2f
5 changed files with 26 additions and 4 deletions

View file

@ -368,6 +368,9 @@ qboolean CL_OpenAVIForWriting( const char *fileName )
afd.a.rate = dma.speed; afd.a.rate = dma.speed;
afd.a.format = WAV_FORMAT_PCM; afd.a.format = WAV_FORMAT_PCM;
afd.a.channels = dma.channels; 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.bits = dma.samplebits;
afd.a.sampleSize = ( afd.a.bits / 8 ) * afd.a.channels; afd.a.sampleSize = ( afd.a.bits / 8 ) * afd.a.channels;

View file

@ -100,7 +100,7 @@ void S_Base_SoundInfo(void) {
} else { } else {
Com_Printf("%5d stereo\n", dma.channels - 1); Com_Printf("%5d stereo\n", dma.channels - 1);
Com_Printf("%5d samples\n", dma.samples); 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 submission_chunk\n", dma.submission_chunk);
Com_Printf("%5d speed\n", dma.speed); Com_Printf("%5d speed\n", dma.speed);
Com_Printf("%p dma buffer\n", dma.buffer); Com_Printf("%p dma buffer\n", dma.buffer);

View file

@ -67,6 +67,7 @@ typedef struct {
int samples; // mono samples in buffer int samples; // mono samples in buffer
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 speed; int speed;
byte *buffer; byte *buffer;
} dma_t; } dma_t;

View file

@ -184,7 +184,22 @@ void S_TransferPaintBuffer(int endtime)
out_idx = s_paintedtime * dma.channels & out_mask; out_idx = s_paintedtime * dma.channels & out_mask;
step = 3 - dma.channels; 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; short *out = (short *) pbuf;
while (count--) while (count--)

View file

@ -96,7 +96,9 @@ static struct
{ AUDIO_U16LSB, "AUDIO_U16LSB" }, { AUDIO_U16LSB, "AUDIO_U16LSB" },
{ AUDIO_S16LSB, "AUDIO_S16LSB" }, { AUDIO_S16LSB, "AUDIO_S16LSB" },
{ AUDIO_U16MSB, "AUDIO_U16MSB" }, { 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 ); static int formatToStringTableSize = ARRAY_LEN( formatToStringTable );
@ -228,7 +230,8 @@ qboolean SNDDMA_Init(void)
} }
dmapos = 0; 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.channels = obtained.channels;
dma.samples = tmp; dma.samples = tmp;
dma.submission_chunk = 1; dma.submission_chunk = 1;