diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index f575de80ef..c58f25816a 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -22,12 +22,26 @@ // #define AUDIO_TO_FILE -static const s8 f[5][2] = -{ { 0, 0 }, -{ 60, 0 }, -{ 115, -52 }, -{ 98, -55 }, -{ 122, -60 } }; +static const s8 f[16][2] = { + { 0, 0 }, + { 60, 0 }, + { 115, -52 }, + { 98, -55 }, + { 122, -60 }, + + // Padding to prevent overflow. + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, +}; void VagDecoder::Start(u32 data, int vagSize, bool loopEnabled) { loopEnabled_ = loopEnabled; @@ -47,9 +61,6 @@ void VagDecoder::DecodeBlock(u8 *&readp) { int predict_nr = *readp++; int shift_factor = predict_nr & 0xf; predict_nr >>= 4; - if (predict_nr >= sizeof(f) / sizeof(f[0])) { - predict_nr = 0; - } int flags = *readp++; if (flags == 7) { end_ = true; @@ -66,14 +77,9 @@ void VagDecoder::DecodeBlock(u8 *&readp) { for (int i = 0; i < 28; i += 2) { int d = *readp++; int s = (short)((d & 0xf) << 12); - samples[i] = s >> shift_factor; + DecodeSample(i, s >> shift_factor, predict_nr); s = (short)((d & 0xf0) << 8); - samples[i + 1] = s >> shift_factor; - } - for (int i = 0; i < 28; i++) { - samples[i] = (int) (samples[i] + ((s_1 * f[predict_nr][0] + s_2 * f[predict_nr][1]) >> 6)); - s_2 = s_1; - s_1 = samples[i]; + DecodeSample(i + 1, s >> shift_factor, predict_nr); } curSample = 0; curBlock_++; @@ -82,6 +88,12 @@ void VagDecoder::DecodeBlock(u8 *&readp) { } } +inline void VagDecoder::DecodeSample(int i, int sample, int predict_nr) { + samples[i] = (int) (sample + ((s_1 * f[predict_nr][0] + s_2 * f[predict_nr][1]) >> 6)); + s_2 = s_1; + s_1 = samples[i]; +} + void VagDecoder::GetSamples(s16 *outSamples, int numSamples) { if (end_) { memset(outSamples, 0, numSamples * sizeof(s16)); diff --git a/Core/HW/SasAudio.h b/Core/HW/SasAudio.h index e39b84fcf6..5426edafd7 100644 --- a/Core/HW/SasAudio.h +++ b/Core/HW/SasAudio.h @@ -86,6 +86,7 @@ public: void DoState(PointerWrap &p); private: + void DecodeSample(int i, int sample, int predict_nr); int samples[28]; int curSample;