Correct fix for DSF ADPCM decoder.
This commit is contained in:
parent
0bc20e792d
commit
540ca59b50
1 changed files with 14 additions and 15 deletions
|
@ -97,9 +97,12 @@ static const uint8 envdecayvalue[0x3D][4] = {
|
||||||
/* 38-3C */ {4,4,4,4},{8,4,4,4},{8,4,8,4},{8,8,8,4},{8,8,8,8}
|
/* 38-3C */ {4,4,4,4},{8,4,4,4},{8,4,8,4},{8,8,8,4},{8,8,8,8}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const float adpcmscale[8] = {
|
static const int adpcmscale[8] = {
|
||||||
0.8984375f, 0.8984375f, 0.8984375f, 0.8984375f,
|
0xE6, 0xE6, 0xE6, 0xE6, 0x133, 0x199, 0x200, 0x266
|
||||||
1.1992188f, 1.5976563f, 2.0000000f, 2.3984375f
|
};
|
||||||
|
|
||||||
|
static const int adpcmdiff[8] = {
|
||||||
|
1, 3, 5, 7, 9, 11, 13, 15
|
||||||
};
|
};
|
||||||
|
|
||||||
static const sint32 qtable[32] = {
|
static const sint32 qtable[32] = {
|
||||||
|
@ -1994,20 +1997,16 @@ static void readnextsample(
|
||||||
s = *(uint8*)(((uint8*)(state->ram_ptr)) + (((chan->sampleaddr + (chan->playpos >> 1)) ^ (state->mem_byte_address_xor)) & (state->ram_mask)));
|
s = *(uint8*)(((uint8*)(state->ram_ptr)) + (((chan->sampleaddr + (chan->playpos >> 1)) ^ (state->mem_byte_address_xor)) & (state->ram_mask)));
|
||||||
s >>= 4 * ((chan->playpos & 1) ^ 0);
|
s >>= 4 * ((chan->playpos & 1) ^ 0);
|
||||||
s &= 0xF;
|
s &= 0xF;
|
||||||
{ sint32 sign = 1 - ((s >> 2) & 2);
|
{ sint32 out = (chan->adpcmstep * adpcmdiff[s & 7]) / 8;
|
||||||
float step = (float)(chan->adpcmstep);
|
if(out > ( 0x7FFF)) { out = 0x7FFF; }
|
||||||
float s1 = (float)((s >> 2) & 1);
|
out*=1-((s >> 2) & 2);
|
||||||
float s2 = (float)((s >> 1) & 1);
|
|
||||||
float s4 = (float)(s & 1);
|
|
||||||
sint32 out = (int)((step * s1) + ((step * s2) / 2.0f) + ((step * s4) / 4.0f) + (step / 8.0f));
|
|
||||||
if(out > 0x7FFF) { out = 0x7FFF; }
|
|
||||||
out*=sign;
|
|
||||||
out+=chan->adpcmprev;
|
out+=chan->adpcmprev;
|
||||||
if(out > 0x7FFF) { out = 0x7FFF; }
|
if(out > ( 0x7FFF)) { out = ( 0x7FFF); /* logf("<adpcmoverflow>"); */ }
|
||||||
if(out < -0x8000) { out = -0x8000; }
|
if(out < (-0x8000)) { out = (-0x8000); /* logf("<adpcmunderflow>"); */ }
|
||||||
chan->adpcmstep = (int)((float)chan->adpcmstep * adpcmscale[s&7]);
|
chan->adpcmstep = (chan->adpcmstep * adpcmscale[s & 7]) >> 8;
|
||||||
if(chan->adpcmstep > 0x6000) { chan->adpcmstep = 0x6000; }
|
if(chan->adpcmstep > 0x6000) { chan->adpcmstep = 0x6000; }
|
||||||
if(chan->adpcmstep < 0x7F) { chan->adpcmstep = 0x7F; }
|
if(chan->adpcmstep < 0x007F) { chan->adpcmstep = 0x007F; }
|
||||||
|
chan->adpcmprev = out;
|
||||||
s = out;
|
s = out;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue