Zelda HLE: Fix reverb in the GC IPL.

Adds a missing destination buffer, and support post-filtering.
This commit is contained in:
Pierre Bourdon 2014-12-22 05:43:35 +01:00
parent 13ea54628d
commit 8c85a8c8d9
2 changed files with 21 additions and 13 deletions

View File

@ -814,16 +814,22 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
for (u16 i = 0; i < 8; ++i) for (u16 i = 0; i < 8; ++i)
(*last8_samples_buffers[rpb_idx])[i] = buffer[0x50 + i]; (*last8_samples_buffers[rpb_idx])[i] = buffer[0x50 + i];
// Filter the buffer using provided coefficients. auto ApplyFilter = [&]() {
for (u16 i = 0; i < 0x50; ++i) // Filter the buffer using provided coefficients.
{ for (u16 i = 0; i < 0x50; ++i)
s32 sample = 0; {
for (u16 j = 0; j < 8; ++j) s32 sample = 0;
sample += (s32)buffer[i + j] * rpb.filter_coeffs[j]; for (u16 j = 0; j < 8; ++j)
sample >>= 15; sample += (s32)buffer[i + j] * rpb.filter_coeffs[j];
MathUtil::Clamp(&sample, -0x8000, 0x7fff); sample >>= 15;
buffer[i] = sample; MathUtil::Clamp(&sample, -0x8000, 0x7fff);
} buffer[i] = sample;
}
};
// LSB set -> pre-filtering.
if (rpb.enabled & 1)
ApplyFilter();
for (const auto& dest : rpb.dest) for (const auto& dest : rpb.dest)
{ {
@ -840,10 +846,9 @@ void ZeldaAudioRenderer::ApplyReverb(bool post_rendering)
0x50, dest.volume); 0x50, dest.volume);
} }
// TODO: If "enabled" & 2, the filtering should be done post and // LSB not set, bit 1 set -> post-filtering.
// not pre mixing.
if (rpb.enabled & 2) if (rpb.enabled & 2)
PanicAlert("RPB wants post filtering."); ApplyFilter();
for (u16 i = 0; i < 0x50; ++i) for (u16 i = 0; i < 0x50; ++i)
(*reverb_buffers[rpb_idx])[i] = buffer[i]; (*reverb_buffers[rpb_idx])[i] = buffer[i];
@ -876,6 +881,7 @@ ZeldaAudioRenderer::MixingBuffer* ZeldaAudioRenderer::BufferForID(u16 buffer_id)
case 0x0C50: return &m_buf_back_right_reverb; case 0x0C50: return &m_buf_back_right_reverb;
case 0x0DC0: return &m_buf_unk0_reverb; case 0x0DC0: return &m_buf_unk0_reverb;
case 0x0E20: return &m_buf_unk1_reverb; case 0x0E20: return &m_buf_unk1_reverb;
case 0x09A0: return &m_buf_unk0; // Used by the GC IPL as a reverb dest.
default: return nullptr; default: return nullptr;
} }
} }
@ -1501,6 +1507,7 @@ void ZeldaAudioRenderer::DoState(PointerWrap& p)
p.Do(m_buf_back_right_reverb); p.Do(m_buf_back_right_reverb);
p.Do(m_buf_unk0_reverb); p.Do(m_buf_unk0_reverb);
p.Do(m_buf_unk1_reverb); p.Do(m_buf_unk1_reverb);
p.Do(m_buf_unk0);
p.Do(m_resampling_coeffs); p.Do(m_resampling_coeffs);
p.Do(m_const_patterns); p.Do(m_const_patterns);

View File

@ -117,6 +117,7 @@ private:
MixingBuffer m_buf_back_right_reverb{}; MixingBuffer m_buf_back_right_reverb{};
MixingBuffer m_buf_unk0_reverb{}; MixingBuffer m_buf_unk0_reverb{};
MixingBuffer m_buf_unk1_reverb{}; MixingBuffer m_buf_unk1_reverb{};
MixingBuffer m_buf_unk0{};
// Maps a buffer "ID" (really, their address in the DSP DRAM...) to our // Maps a buffer "ID" (really, their address in the DSP DRAM...) to our
// buffers. Returns nullptr if no match is found. // buffers. Returns nullptr if no match is found.