Unverified Commit 4218f337 authored by Jake Stine's avatar Jake Stine Committed by GitHub
Browse files

fix stereo playback and looping logic in WAV decoder (#196)

* fix looping logic bug in WAV streaming decoder.

This was meant to make it into my earlier PR that added non-canonical WAV support. I fixed it over a week ago, but apparently it's hard to keep 5+ simultaneous PRs organized.

* Fix wav stereo sample playback too.

(I had only tested stereo ogg formats so far)
parent 7b5bd3d5
...@@ -351,27 +351,31 @@ static __always_inline int inl_get_sample(const uint8_t* sample_raw, int sz, int ...@@ -351,27 +351,31 @@ static __always_inline int inl_get_sample(const uint8_t* sample_raw, int sz, int
// this is a pseudo template with several cont literal parameters. // this is a pseudo template with several cont literal parameters.
// it should always be agressively inlined. // it should always be agressively inlined.
static __always_inline bool _inl_decode_wav(dec_WavData *data, intmax_t bufsz, mixer_presaturate_t* dst, int bytesPerSample, int chan_src, int chan_dst, float volume, bool loop) static __always_inline bool _inl_decode_wav(dec_WavData *data, intmax_t bufsz, mixer_presaturate_t* dst, int bytesPerSamplePerChan, int chan_src, int chan_dst, float volume, bool loop)
{ {
// a normalized sound sample is considered range -1.0 to 1.0 // a normalized sound sample is considered range -1.0 to 1.0
// 16-bit wav outputs values range 32767 to -32768 // 16-bit wav outputs values range 32767 to -32768
// 8-bit wav is scaled up to 16 bit and then normalized using 16-bit divisor. // 8-bit wav is scaled up to 16 bit and then normalized using 16-bit divisor.
float mul_volume_and_normalize = volume / 32767; float mul_volume_and_normalize = volume / 32767;
int numSamples = data->headc2.Subchunk2Size / bytesPerSample; int bytesPerMultiSample = bytesPerSamplePerChan * chan_src;
for (int j = 0; j < bufsz; j++, data->pos += (bytesPerSample * chan_src)) int byteLen = data->headc2.Subchunk2Size;
int numSamples = data->headc2.Subchunk2Size / bytesPerMultiSample;
for (int j = 0; j < bufsz; j++, data->pos += bytesPerMultiSample)
{ {
uint8_t sample_raw[8]; uint8_t sample_raw[8];
int readResult = 0; int readResult = 0;
if (data->pos < numSamples)
readResult = (int)fread(sample_raw, bytesPerSample * chan_src, 1, data->fp); reloadSample:
if (data->pos < byteLen)
readResult = (int)fread(sample_raw, bytesPerMultiSample, 1, data->fp);
if (!readResult) if (!readResult)
{ {
intmax_t seekpos = decWav_CalcOffsetDataStart(data) + data->pos; dbg_assertf(data->pos == ftell(data->fp) - decWav_CalcOffsetDataStart(data), "numSamples=%jd byteLen=%jd dataPos=%jd and ftell=%jd",
dbg_assertf(ftell(data->fp) == seekpos, "numSamples=%jd dataPos=%jd and ftell=%jd", (intmax_t)numSamples, (intmax_t)byteLen, (intmax_t)data->pos, (intmax_t)ftell(data->fp)
(intmax_t)numSamples, (intmax_t)data->pos, ftell(data->fp)
); );
if (!loop) if (!loop)
...@@ -383,22 +387,22 @@ static __always_inline bool _inl_decode_wav(dec_WavData *data, intmax_t bufsz, m ...@@ -383,22 +387,22 @@ static __always_inline bool _inl_decode_wav(dec_WavData *data, intmax_t bufsz, m
} }
data->pos = 0; data->pos = 0;
fseek(data->fp, seekpos, SEEK_SET); fseek(data->fp, decWav_CalcOffsetDataStart(data), SEEK_SET);
--j; continue; // attempt to re-read sample. --j; goto reloadSample; // attempt to re-read sample.
} }
if (chan_src == 2) if (chan_src == 2)
{ {
if (chan_dst == 1) if (chan_dst == 1)
{ {
dst[j] += inl_get_sample(sample_raw, bytesPerSample, 0) * mul_volume_and_normalize; dst[j] += inl_get_sample(sample_raw, bytesPerSamplePerChan, 0) * mul_volume_and_normalize;
dst[j] += inl_get_sample(sample_raw, bytesPerSample, 1) * mul_volume_and_normalize; dst[j] += inl_get_sample(sample_raw, bytesPerSamplePerChan, 1) * mul_volume_and_normalize;
} }
if (chan_dst == 2) if (chan_dst == 2)
{ {
dst[(j*2)+0] += inl_get_sample(sample_raw, bytesPerSample, 0) * mul_volume_and_normalize; dst[(j*2)+0] += inl_get_sample(sample_raw, bytesPerSamplePerChan, 0) * mul_volume_and_normalize;
dst[(j*2)+1] += inl_get_sample(sample_raw, bytesPerSample, 1) * mul_volume_and_normalize; dst[(j*2)+1] += inl_get_sample(sample_raw, bytesPerSamplePerChan, 1) * mul_volume_and_normalize;
} }
} }
...@@ -406,19 +410,19 @@ static __always_inline bool _inl_decode_wav(dec_WavData *data, intmax_t bufsz, m ...@@ -406,19 +410,19 @@ static __always_inline bool _inl_decode_wav(dec_WavData *data, intmax_t bufsz, m
{ {
if (chan_dst == 1) if (chan_dst == 1)
{ {
dst[j] += inl_get_sample(sample_raw, bytesPerSample, 0) * mul_volume_and_normalize; dst[j] += inl_get_sample(sample_raw, bytesPerSamplePerChan, 0) * mul_volume_and_normalize;
} }
if (chan_dst == 2) if (chan_dst == 2)
{ {
dst[(j*2)+0] += inl_get_sample(sample_raw, bytesPerSample, 0) * mul_volume_and_normalize; dst[(j*2)+0] += inl_get_sample(sample_raw, bytesPerSamplePerChan, 0) * mul_volume_and_normalize;
dst[(j*2)+1] += inl_get_sample(sample_raw, bytesPerSample, 0) * mul_volume_and_normalize; dst[(j*2)+1] += inl_get_sample(sample_raw, bytesPerSamplePerChan, 0) * mul_volume_and_normalize;
} }
} }
} }
dbg_assertf(ftell(data->fp) == decWav_CalcOffsetDataStart(data) + data->pos, "numSamples=%jd dataPos=%jd and ftell=%jd", dbg_assertf(data->pos == ftell(data->fp) - decWav_CalcOffsetDataStart(data), "numSamples=%jd byteLen=%jd dataPos=%jd and ftell=%jd",
(intmax_t)numSamples, (intmax_t)data->pos, ftell(data->fp) (intmax_t)numSamples, (intmax_t)byteLen, (intmax_t)data->pos, (intmax_t)ftell(data->fp)
); );
return 0; return 0;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment