DSP HLE
* Some fixes to linear interpolation * Adds interpolation to ADPCM samples * Relaxed a volume limit in ADPCM_Vol Fixed: - Frac rolls over one iteration before samplePos advances. Can introduce noise similar to flipping samples (1234 => 1214). Introduced oldFrac to fix this. This isn't as noticeable as it probably should be because of below. - When samplePos doesn't advance it interpolates between two copies of the same sample which actually does nothing. Changed it to always use the current and next sample. - When frac is 0 you should get 100% of yn2 instead of ~99% added a +yn2 to balance it. Other changes: - Added linear interpolation for ADPCM. Sounds like a good idea. - Set ADPCM_Vol to clamp to x8000 instead of x4e20. Some games will play some sounds at x8000 volume anyways since the volume is applied before this. Lower limit can result in quiet music (x4e20) but some loud ambient sounds (0x8000). git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6041 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
fe0f25c737
commit
340912dc1e
|
@ -83,7 +83,8 @@ inline u16 ADPCM_Vol(u16 vol, u16 delta)
|
||||||
//if (mixer_control > 1000 && x > mixer_control) x = mixer_control; // maybe mixer_control also
|
//if (mixer_control > 1000 && x > mixer_control) x = mixer_control; // maybe mixer_control also
|
||||||
// has a volume target?
|
// has a volume target?
|
||||||
//if (x >= 0x7fff) x = 0x7fff; // this seems a little high
|
//if (x >= 0x7fff) x = 0x7fff; // this seems a little high
|
||||||
if (x >= 0x4e20) x = 0x4e20; // add a definitive limit at 20 000
|
//if (x >= 0x4e20) x = 0x4e20; // add a definitive limit at 20 000
|
||||||
|
if (x >= 0x8000) x = 0x8000; // clamp to 32768;
|
||||||
return x; // update volume
|
return x; // update volume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,7 @@ inline void MixAddVoice(ParamBlockType &pb,
|
||||||
for (int s = 0; s < _iSize; s++)
|
for (int s = 0; s < _iSize; s++)
|
||||||
{
|
{
|
||||||
int sample = 0;
|
int sample = 0;
|
||||||
|
u32 oldFrac = frac;
|
||||||
frac += ratio;
|
frac += ratio;
|
||||||
u32 newSamplePos = samplePos + (frac >> 16); //whole number of frac
|
u32 newSamplePos = samplePos + (frac >> 16); //whole number of frac
|
||||||
|
|
||||||
|
@ -164,36 +165,37 @@ inline void MixAddVoice(ParamBlockType &pb,
|
||||||
switch (pb.audio_addr.sample_format)
|
switch (pb.audio_addr.sample_format)
|
||||||
{
|
{
|
||||||
case AUDIOFORMAT_PCM8:
|
case AUDIOFORMAT_PCM8:
|
||||||
// TODO - the linear interpolation code below is somewhat suspicious
|
pb.adpcm.yn2 = ((s8)g_dspInitialize.pARAM_Read_U8(samplePos)) << 8; //current sample
|
||||||
pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample
|
pb.adpcm.yn1 = ((s8)g_dspInitialize.pARAM_Read_U8(samplePos + 1)) << 8; //next sample
|
||||||
pb.adpcm.yn1 = ((s8)g_dspInitialize.pARAM_Read_U8(samplePos)) << 8;
|
|
||||||
|
|
||||||
if (pb.src_type == SRCTYPE_NEAREST)
|
if (pb.src_type == SRCTYPE_NEAREST)
|
||||||
{
|
sample = pb.adpcm.yn2;
|
||||||
sample = pb.adpcm.yn1;
|
|
||||||
}
|
|
||||||
else // linear interpolation
|
else // linear interpolation
|
||||||
{
|
sample = (pb.adpcm.yn1 * (u16)oldFrac + pb.adpcm.yn2 * (u16)(0xFFFF - oldFrac) + pb.adpcm.yn2) >> 16;
|
||||||
sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
samplePos = newSamplePos;
|
samplePos = newSamplePos;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUDIOFORMAT_PCM16:
|
case AUDIOFORMAT_PCM16:
|
||||||
// TODO - the linear interpolation code below is somewhat suspicious
|
pb.adpcm.yn2 = (s16)(u16)((g_dspInitialize.pARAM_Read_U8(samplePos * 2) << 8) | (g_dspInitialize.pARAM_Read_U8((samplePos * 2 + 1)))); //current sample
|
||||||
pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample
|
pb.adpcm.yn1 = (s16)(u16)((g_dspInitialize.pARAM_Read_U8((samplePos + 1) * 2) << 8) | (g_dspInitialize.pARAM_Read_U8(((samplePos + 1) * 2 + 1)))); //next sample
|
||||||
pb.adpcm.yn1 = (s16)(u16)((g_dspInitialize.pARAM_Read_U8(samplePos * 2) << 8) | (g_dspInitialize.pARAM_Read_U8((samplePos * 2 + 1))));
|
|
||||||
if (pb.src_type == SRCTYPE_NEAREST)
|
if (pb.src_type == SRCTYPE_NEAREST)
|
||||||
sample = pb.adpcm.yn1;
|
sample = pb.adpcm.yn2;
|
||||||
else // linear interpolation
|
else // linear interpolation
|
||||||
sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16;
|
sample = (pb.adpcm.yn1 * (u16)oldFrac + pb.adpcm.yn2 * (u16)(0xFFFF - oldFrac) + pb.adpcm.yn2) >> 16;
|
||||||
|
|
||||||
samplePos = newSamplePos;
|
samplePos = newSamplePos;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUDIOFORMAT_ADPCM:
|
case AUDIOFORMAT_ADPCM:
|
||||||
sample = ADPCM_Step(pb.adpcm, samplePos, newSamplePos, frac);
|
ADPCM_Step(pb.adpcm, samplePos, newSamplePos, frac);
|
||||||
|
|
||||||
|
if (pb.src_type == SRCTYPE_NEAREST)
|
||||||
|
sample = pb.adpcm.yn2;
|
||||||
|
else // linear interpolation
|
||||||
|
sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac) + pb.adpcm.yn2) >> 16; //adpcm moves on frac
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue