Zelda HLE: Implement sample sources 4, 7, 11 and 12.

Just 4 different versions of the same sample source, using a different constant
pattern uploaded to the DSP during command 01.
This commit is contained in:
Pierre Bourdon 2014-12-21 17:08:57 +01:00
parent 6c61ee6278
commit bfff0a72df
2 changed files with 47 additions and 1 deletions

View File

@ -226,7 +226,10 @@ void ZeldaUCode::RunPendingCommands()
resampling_coeffs[i] = Common::swap16(data_ptr[i]);
m_renderer.SetResamplingCoeffs(std::move(resampling_coeffs));
// TODO: 0x100 more words here to figure out.
std::array<s16, 0x100> const_patterns;
for (size_t i = 0; i < 0x100; ++i)
const_patterns[i] = Common::swap16(data_ptr[0x100 + i]);
m_renderer.SetConstPatterns(std::move(const_patterns));
std::array<s16, 0x80> sine_table;
for (size_t i = 0; i < 0x80; ++i)
@ -491,6 +494,15 @@ struct ZeldaAudioRenderer::VPB
// Simple saw wave at 100% amplitude and frequency controlled via the
// resampling ratio.
SRC_SAW_WAVE = 1,
// Breaking the numerical ordering for these, but they are all related.
// Simple pattern stored in the data downloaded by command 01. Playback
// frequency is controlled by the resampling ratio.
SRC_CONST_PATTERN_0 = 7,
SRC_CONST_PATTERN_1 = 4,
SRC_CONST_PATTERN_2 = 11,
SRC_CONST_PATTERN_3 = 12,
// Samples stored in ARAM in PCM8 format, at an arbitrary sampling rate
// (resampling is applied).
SRC_PCM8_FROM_ARAM = 8,
@ -948,6 +960,36 @@ void ZeldaAudioRenderer::LoadInputSamples(MixingBuffer* buffer, VPB* vpb)
break;
}
case VPB::SRC_CONST_PATTERN_0:
case VPB::SRC_CONST_PATTERN_1:
case VPB::SRC_CONST_PATTERN_2:
case VPB::SRC_CONST_PATTERN_3:
{
const u16 PATTERN_SIZE = 0x40;
std::map<u16, u16> samples_source_to_pattern = {
{ VPB::SRC_CONST_PATTERN_0, 0 },
{ VPB::SRC_CONST_PATTERN_1, 1 },
{ VPB::SRC_CONST_PATTERN_2, 2 },
{ VPB::SRC_CONST_PATTERN_3, 3 },
};
u16 pattern_idx = samples_source_to_pattern[vpb->samples_source_type];
u16 pattern_offset = pattern_idx * PATTERN_SIZE;
s16* pattern = m_const_patterns.data() + pattern_offset;
u32 pos = vpb->current_pos_frac << 6; // log2(PATTERN_SIZE)
u32 step = vpb->resampling_ratio << 5;
for (size_t i = 0; i < buffer->size(); ++i)
{
(*buffer)[i] = pattern[pos >> 16];
pos = (pos + step) % (PATTERN_SIZE << 16);
}
vpb->current_pos_frac = pos >> 6;
break;
}
case VPB::SRC_PCM8_FROM_ARAM:
DownloadPCM8SamplesFromARAM(raw_input_samples.data() + 4, vpb,
NeededRawSamplesCount(*vpb));

View File

@ -16,6 +16,7 @@ public:
void FinalizeFrame();
void SetSineTable(std::array<s16, 0x80>&& sine_table) { m_sine_table = sine_table; }
void SetConstPatterns(std::array<s16, 0x100>&& patterns) { m_const_patterns = patterns; }
void SetResamplingCoeffs(std::array<s16, 0x100>&& coeffs) { m_resampling_coeffs = coeffs; }
void SetAfcCoeffs(std::array<s16, 0x20>&& coeffs) { m_afc_coeffs = coeffs; }
void SetVPBBaseAddress(u32 addr) { m_vpb_base_addr = addr; }
@ -125,6 +126,9 @@ private:
// [0.0;pi/4] (sin(x) in [1.0;0.0]), in 1.15 fixed format.
std::array<s16, 0x80> m_sine_table{};
// Const patterns used for some voice samples source. 4 x 0x40 samples.
std::array<s16, 0x100> m_const_patterns{};
// Fills up a buffer with the input samples for a voice, represented by its
// VPB.
void LoadInputSamples(MixingBuffer* buffer, VPB* vpb);