Fix AUX volume mixing in AXWii: implement volume ramping and MixAdd properly. Home menu sounds now work properly.

This commit is contained in:
Pierre Bourdon 2013-03-29 22:22:24 +01:00
parent ef501137be
commit 4b09f525f6
2 changed files with 29 additions and 3 deletions

View File

@ -29,7 +29,8 @@
CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC)
: CUCode_AX(dsp_hle, l_CRC)
: CUCode_AX(dsp_hle, l_CRC),
m_last_aux_volume(0x8000)
{
WARN_LOG(DSPHLE, "Instantiating CUCode_AXWii");
}
@ -269,6 +270,22 @@ void CUCode_AXWii::ProcessPBList(u32 pb_addr)
void CUCode_AXWii::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr, u16 volume)
{
u16 prev_volume = m_last_aux_volume;
// Generate a volume ramp going from prev_volume to volume.
//
// The AXWii UCode uses integer arithmetic with 2 multipliers because it
// can't get enough precision to represent 1 / 96. We can use floating
// point arithmetic, so we will - it makes the code more readable and more
// precise.
u16 volume_ramp[96];
float curr_volume = prev_volume;
for (int i = 0; i < 96; ++i)
{
volume_ramp[i] = (u16)curr_volume;
curr_volume += (volume - prev_volume) / 96.0;
}
int* buffers[3] = { 0 };
int* main_buffers[3] = {
m_samples_left,
@ -311,9 +328,12 @@ void CUCode_AXWii::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr, u16
for (u32 i = 0; i < 3; ++i)
for (u32 j = 0; j < 3 * 32; ++j)
{
s64 new_val = main_buffers[i][j] + Common::swap32(*ptr++);
main_buffers[i][j] = (new_val * volume) >> 15;
s64 sample = (s64)(s32)Common::swap32(*ptr++);
sample *= volume_ramp[j];
main_buffers[i][j] += (s32)(sample >> 15);
}
m_last_aux_volume = volume;
}
void CUCode_AXWii::OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume)
@ -397,4 +417,6 @@ void CUCode_AXWii::DoState(PointerWrap &p)
p.Do(m_samples_aux1);
p.Do(m_samples_aux2);
p.Do(m_samples_aux3);
p.Do(m_last_aux_volume);
}

View File

@ -29,6 +29,7 @@ public:
virtual void DoState(PointerWrap &p);
protected:
// Additional AUX buffers
int m_samples_auxC_left[32 * 3];
int m_samples_auxC_right[32 * 3];
int m_samples_auxC_surround[32 * 3];
@ -43,6 +44,9 @@ protected:
int m_samples_wm3[6 * 3];
int m_samples_aux3[6 * 3];
// Last MixAUXSamples volume value. Used to generate volume ramps.
u16 m_last_aux_volume;
// Convert a mixer_control bitfield to our internal representation for that
// value. Required because that bitfield has a different meaning in some
// versions of AX.