From e80bb110b399e217638b4c7d980b19697c380032 Mon Sep 17 00:00:00 2001 From: luigi__ Date: Sun, 28 Dec 2008 23:40:15 +0000 Subject: [PATCH] A few optimizations to the ADPCM sound decoding func. --- desmume/src/SPU.cpp | 80 ++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/desmume/src/SPU.cpp b/desmume/src/SPU.cpp index e25def70e..678134bb2 100644 --- a/desmume/src/SPU.cpp +++ b/desmume/src/SPU.cpp @@ -70,10 +70,26 @@ s16 wavedutytbl[8][8] = { { -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF } }; +int precalcdifftbl[89][16]; +int precalcindextbl[89][8]; + FILE *spufp=NULL; ////////////////////////////////////////////////////////////////////////////// +template +static INLINE T MinMax(T val, T min, T max) +{ + if (val < min) + return min; + else if (val > max) + return max; + + return val; +} + +////////////////////////////////////////////////////////////////////////////// + int SPU_ChangeSoundCore(int coreid, int buffersize) { int i; @@ -129,9 +145,28 @@ SoundInterface_struct *SPU_SoundCore() int SPU_Init(int coreid, int buffersize) { + int i, j; + SPU_core = new SPU_struct(740); SPU_Reset(); + for(i = 0; i < 16; i++) + { + for(j = 0; j < 89; j++) + { + precalcdifftbl[j][i] = (((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8); + if(i & 0x8) precalcdifftbl[j][i] = -precalcdifftbl[j][i]; + } + } + + for(int i = 0; i < 8; i++) + { + for(j = 0; j < 89; j++) + { + precalcindextbl[j][i] = MinMax((j + indextbl[i]), 0, 88); + } + } + return SPU_ChangeSoundCore(coreid, buffersize); } @@ -239,7 +274,7 @@ void SPU_struct::KeyOn(int channel) { thischan.buf8 = (s8*)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; thischan.pcm16b = (s16)((thischan.buf8[1] << 8) | thischan.buf8[0]); - thischan.pcm16b_last = 0; + thischan.pcm16b_last = thischan.pcm16b; thischan.index = thischan.buf8[2] & 0x7F; thischan.lastsampcnt = 7; thischan.sampcnt = 8; @@ -593,11 +628,12 @@ static INLINE void Fetch8BitData(channel_struct *chan, s32 *data) { #ifdef SPU_INTERPOLATE int loc = (int)chan->sampcnt; - s32 a = (s32)chan->buf8[loc] << 8; - if(loclength-1) { - double ratio = chan->sampcnt-loc; - s32 b = (s32)chan->buf8[loc+1] << 8; - a = (1-ratio)*a + ratio*b; + s32 a = (s32)(chan->buf8[loc] << 8); + if(loc < (chan->length << 2) - 1) { + /* double ratio = chan->sampcnt-loc;*/ + s32 b = (s32)(chan->buf8[loc + 1] << 8); + /* a = (1-ratio)*a + ratio*b;*/ + a = Interpolate(a, b, chan->sampcnt); } *data = a; #else @@ -612,10 +648,11 @@ static INLINE void Fetch16BitData(channel_struct *chan, s32 *data) #ifdef SPU_INTERPOLATE int loc = (int)chan->sampcnt; s32 a = (s32)chan->buf16[loc]; - if(loclength-1) { - double ratio = chan->sampcnt-loc; - s32 b = (s32)chan->buf16[loc+1]; - a = (1-ratio)*a + ratio*b; + if(loc < (chan->length << 1) - 1) { + //double ratio = chan->sampcnt-loc; + s32 b = (s32)chan->buf16[loc + 1]; + //a = (1-ratio)*a + ratio*b; + a = Interpolate(a, b, chan->sampcnt); } *data = a; #else @@ -625,18 +662,6 @@ static INLINE void Fetch16BitData(channel_struct *chan, s32 *data) ////////////////////////////////////////////////////////////////////////////// -static INLINE int MinMax(int val, int min, int max) -{ - if (val < min) - return min; - else if (val > max) - return max; - - return val; -} - -////////////////////////////////////////////////////////////////////////////// - static INLINE void FetchADPCMData(channel_struct *chan, s32 *data) { u8 data4bit; @@ -661,15 +686,17 @@ static INLINE void FetchADPCMData(channel_struct *chan, s32 *data) else data4bit = chan->buf8[i >> 1] & 0xF; - diff = ((data4bit & 0x7) * 2 + 1) * adpcmtbl[chan->index] / 8; + /*diff = ((data4bit & 0x7) * 2 + 1) * adpcmtbl[chan->index] / 8; if (data4bit & 0x8) - diff = -diff; + diff = -diff;*/ + diff = precalcdifftbl[chan->index][data4bit]; #ifdef SPU_INTERPOLATE chan->pcm16b_last = chan->pcm16b; #endif - chan->pcm16b = (s16)MinMax(chan->pcm16b+diff, -0x8000, 0x7FFF); - chan->index = MinMax(chan->index+indextbl[data4bit & 0x7], 0, 88); + chan->pcm16b = MinMax(chan->pcm16b+diff, -0x8000, 0x7FFF); + //chan->index = MinMax(chan->index+indextbl[data4bit & 0x7], 0, 88); + chan->index = precalcindextbl[chan->index][data4bit & 0x7]; } chan->lastsampcnt = chan->sampcnt; @@ -1325,6 +1352,7 @@ void SNDFileUpdateAudio(s16 *buffer, u32 num_samples) size_t elems_written; if (spufp) elems_written = fwrite((void *)buffer, num_samples*2, 2, spufp); + INFO("%i written\n", elems_written); } //////////////////////////////////////////////////////////////////////////////