mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
DSPHLE: Attempt at type 0x21 emulation. Enough for zelda ww intro music to play in a strange choppy way, not enough for it to stop hanging :p
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3767 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -102,6 +102,14 @@ CUCode_Zelda::~CUCode_Zelda()
|
|||||||
delete [] m_RightBuffer;
|
delete [] m_RightBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 *CUCode_Zelda::GetARAMPointer(u32 address)
|
||||||
|
{
|
||||||
|
if (m_CRC == 0xD643001F) // SMG
|
||||||
|
return (u8 *)(g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr)) + address;
|
||||||
|
else
|
||||||
|
return (u8 *)(g_dspInitialize.pGetARAMPointer()) + address;
|
||||||
|
}
|
||||||
|
|
||||||
bool CUCode_Zelda::LuigiStyle() const
|
bool CUCode_Zelda::LuigiStyle() const
|
||||||
{
|
{
|
||||||
switch (m_CRC)
|
switch (m_CRC)
|
||||||
|
@ -70,9 +70,9 @@ union ZeldaVoicePB
|
|||||||
u16 Unk2F; // 0x2F | unknown
|
u16 Unk2F; // 0x2F | unknown
|
||||||
u16 CurSampleFrac; // 0x30 | Fractional part of the current sample position
|
u16 CurSampleFrac; // 0x30 | Fractional part of the current sample position
|
||||||
u16 Unk31; // 0x31 | unknown / unused
|
u16 Unk31; // 0x31 | unknown / unused
|
||||||
u16 CurBlock; // 0x32 | current block?
|
u16 CurBlock; // 0x32 | current block? used by zelda's AFC decoder. we don't need it.
|
||||||
u16 FixedSample; // 0x33 | sample value for "blank" voices
|
u16 FixedSample; // 0x33 | sample value for "blank" voices
|
||||||
u32 RestartPos; // 0x34 | restart pos
|
u32 RestartPos; // 0x34 | restart pos / "loop start offset"
|
||||||
u16 Unk36[2]; // 0x36 | unknown // loaded at 0adc/ZWW in 0x21 decoder
|
u16 Unk36[2]; // 0x36 | unknown // loaded at 0adc/ZWW in 0x21 decoder
|
||||||
u32 CurAddr; // 0x38 | current address
|
u32 CurAddr; // 0x38 | current address
|
||||||
u32 RemLength; // 0x3A | remaining length
|
u32 RemLength; // 0x3A | remaining length
|
||||||
@ -96,8 +96,8 @@ union ZeldaVoicePB
|
|||||||
// Read-only part
|
// Read-only part
|
||||||
u16 Format; // 0x80 | audio format
|
u16 Format; // 0x80 | audio format
|
||||||
u16 RepeatMode; // 0x81 | 0 = one-shot, non zero = loop
|
u16 RepeatMode; // 0x81 | 0 = one-shot, non zero = loop
|
||||||
u16 Unk82; // 0x82 | unknown
|
u16 LoopYN1; // 0x82 | YN1 reload (when AFC loops)
|
||||||
u16 Unk83; // 0x83 | unknown
|
u16 LoopYN2; // 0x83 | YN2 reload (when AFC loops)
|
||||||
u16 Unk84; // 0x84 | IIR Filter # coefs?
|
u16 Unk84; // 0x84 | IIR Filter # coefs?
|
||||||
u16 StopOnSilence; // 0x85 | Stop on silence? (Flag for something volume related. Decides the weird stuff at 035a/ZWW, alco 0cd3)
|
u16 StopOnSilence; // 0x85 | Stop on silence? (Flag for something volume related. Decides the weird stuff at 035a/ZWW, alco 0cd3)
|
||||||
u16 Unk86; // 0x86 | unknown
|
u16 Unk86; // 0x86 | unknown
|
||||||
@ -112,7 +112,7 @@ union ZeldaVoicePB
|
|||||||
u16 Padding3[0x7]; // 0xa9 | padding
|
u16 Padding3[0x7]; // 0xa9 | padding
|
||||||
u16 Padding4[0x10]; // 0xb0 | padding
|
u16 Padding4[0x10]; // 0xb0 | padding
|
||||||
};
|
};
|
||||||
u16 raw[0xc0];
|
u16 raw[0xc0]; // WARNING-do not use on parts of the 32-bit values - they are swapped!
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -227,6 +227,8 @@ private:
|
|||||||
|
|
||||||
void ExecuteList();
|
void ExecuteList();
|
||||||
|
|
||||||
|
u8 *GetARAMPointer(u32 address);
|
||||||
|
|
||||||
// AFC decoder
|
// AFC decoder
|
||||||
static void AFCdecodebuffer(const s16 *coef, const char *input, signed short *out, short *histp, short *hist2p, int type);
|
static void AFCdecodebuffer(const s16 *coef, const char *input, signed short *out, short *histp, short *hist2p, int type);
|
||||||
|
|
||||||
@ -237,9 +239,10 @@ private:
|
|||||||
void RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
void RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
||||||
void RenderSynth_RectWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
void RenderSynth_RectWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
||||||
void RenderSynth_SawWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
void RenderSynth_SawWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
||||||
|
|
||||||
void RenderVoice_PCM16(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
void RenderVoice_PCM16(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
||||||
void RenderVoice_AFC(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
void RenderVoice_AFC(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
||||||
void RenderVoice_Raw(ZeldaVoicePB& PB, s32* _Buffer, int _Size);
|
void RenderVoice_Raw(ZeldaVoicePB& PB, s16* _Buffer, int _Size);
|
||||||
|
|
||||||
void Resample(ZeldaVoicePB &PB, int size, s16 *in, s32 *out, bool do_resample = false);
|
void Resample(ZeldaVoicePB &PB, int size, s16 *in, s32 *out, bool do_resample = false);
|
||||||
|
|
||||||
|
@ -98,9 +98,8 @@ void CUCode_Zelda::RenderSynth_SawWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size
|
|||||||
s32 ratio = PB.RatioInt * 2;
|
s32 ratio = PB.RatioInt * 2;
|
||||||
s64 pos = PB.CurSampleFrac;
|
s64 pos = PB.CurSampleFrac;
|
||||||
|
|
||||||
for(int i = 0; i < 0x50; i++) {
|
for (int i = 0; i < 0x50; i++) {
|
||||||
pos += ratio;
|
pos += ratio;
|
||||||
|
|
||||||
_Buffer[i] = pos & 0xFFFF;
|
_Buffer[i] = pos & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,54 +104,53 @@ void CUCode_Zelda::Resample(ZeldaVoicePB &PB, int size, s16 *in, s32 *out, bool
|
|||||||
PB.CurSampleFrac = position & 0xFFFF;
|
PB.CurSampleFrac = position & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateSampleCounters10(ZeldaVoicePB &PB)
|
||||||
|
{
|
||||||
|
PB.RemLength = PB.Length - PB.RestartPos;
|
||||||
|
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
|
||||||
|
PB.ReachedEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CUCode_Zelda::RenderVoice_PCM16(ZeldaVoicePB &PB, s16 *_Buffer, int _Size)
|
void CUCode_Zelda::RenderVoice_PCM16(ZeldaVoicePB &PB, s16 *_Buffer, int _Size)
|
||||||
{
|
{
|
||||||
int _RealSize = SizeForResampling(PB, _Size, PB.RatioInt);
|
int _RealSize = SizeForResampling(PB, _Size, PB.RatioInt);
|
||||||
|
|
||||||
if (PB.KeyOff != 0)
|
if (PB.KeyOff != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (PB.NeedsReset)
|
if (PB.NeedsReset)
|
||||||
{
|
{
|
||||||
// 0a7f_UpdateSampleCounters10
|
// 0a7f_UpdateSampleCounters10
|
||||||
PB.RemLength = PB.Length - PB.RestartPos;
|
UpdateSampleCounters10(PB);
|
||||||
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
|
|
||||||
PB.ReachedEnd = 0;
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
PB.ResamplerOldData[i] = 0;
|
PB.ResamplerOldData[i] = 0; // Doesn't belong here, but dunno where to do it.
|
||||||
}
|
}
|
||||||
|
|
||||||
int inpos = 0;
|
int inpos = 0;
|
||||||
int outpos = 0; // Must be before _lRestart
|
int outpos = 0; // Must be before _lRestart
|
||||||
|
|
||||||
_lRestart:
|
|
||||||
if (PB.ReachedEnd)
|
if (PB.ReachedEnd)
|
||||||
{
|
{
|
||||||
|
_lRestart: // retry_0a30
|
||||||
PB.ReachedEnd = 0;
|
PB.ReachedEnd = 0;
|
||||||
if (PB.RepeatMode == 0)
|
if (PB.RepeatMode == 0)
|
||||||
{
|
{
|
||||||
|
while (outpos < _RealSize) // 0a37
|
||||||
|
_Buffer[outpos++] = 0;
|
||||||
PB.KeyOff = 1;
|
PB.KeyOff = 1;
|
||||||
|
|
||||||
|
// I can't find the following two lines in the ucode:
|
||||||
PB.RemLength = 0;
|
PB.RemLength = 0;
|
||||||
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1) + PB.Length;
|
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1) + PB.Length;
|
||||||
while (outpos < _RealSize)
|
|
||||||
_Buffer[outpos++] = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PB.RestartPos = PB.LoopStartPos;
|
PB.RestartPos = PB.LoopStartPos;
|
||||||
PB.RemLength = PB.Length - PB.RestartPos;
|
UpdateSampleCounters10(PB);
|
||||||
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
|
|
||||||
inpos = 0;
|
inpos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 *source;
|
const s16 *source = (const s16*)GetARAMPointer(PB.CurAddr);
|
||||||
if (m_CRC == 0xD643001F) // SMG
|
|
||||||
source = (s16*)(g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr) + PB.CurAddr);
|
|
||||||
else
|
|
||||||
source = (s16*)(g_dspInitialize.pGetARAMPointer() + PB.CurAddr);
|
|
||||||
|
|
||||||
for (; outpos < _RealSize;)
|
for (; outpos < _RealSize;)
|
||||||
{
|
{
|
||||||
@ -237,10 +236,12 @@ restart:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This needs adjustment. It's not right for AFC, was just copied from PCM16.
|
// This needs adjustment. It's not right for AFC, was just copied from PCM16.
|
||||||
// We should also probably reinitialize YN1 and YN2 with something - but with what?
|
|
||||||
PB.RestartPos = PB.LoopStartPos;
|
PB.RestartPos = PB.LoopStartPos;
|
||||||
PB.RemLength = PB.Length - PB.RestartPos;
|
PB.RemLength = PB.Length - PB.RestartPos;
|
||||||
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
|
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
|
||||||
|
|
||||||
|
PB.YN1 = PB.LoopYN1;
|
||||||
|
PB.YN2 = PB.LoopYN2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,106 +296,103 @@ restart:
|
|||||||
// end of block (Zelda 03b2)
|
// end of block (Zelda 03b2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Decoder21_ReadAudio(ZeldaVoicePB &PB, int size, s16 *_Buffer);
|
||||||
|
|
||||||
// Researching what's actually inside the mysterious 0x21 case
|
// Researching what's actually inside the mysterious 0x21 case
|
||||||
// 0x21 seems to really just be reading raw 16-bit audio from RAM (not ARAM).
|
// 0x21 seems to really just be reading raw 16-bit audio from RAM (not ARAM).
|
||||||
void CUCode_Zelda::RenderVoice_Raw(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
// The rules seem to be quite different, though.
|
||||||
|
// It's used for streaming, not for one-shot or looped sample playback.
|
||||||
|
void CUCode_Zelda::RenderVoice_Raw(ZeldaVoicePB &PB, s16 *_Buffer, int _Size)
|
||||||
{
|
{
|
||||||
float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
|
// Decoder0x21 starts here.
|
||||||
u32 _ratio = (PB.RatioInt << 16);
|
int _RealSize = SizeForResampling(PB, _Size, PB.RatioInt);
|
||||||
s64 ratio = (_ratio * ratioFactor) * 16;
|
|
||||||
|
|
||||||
s64 samples_to_read;
|
// Decoder0x21Core starts here.
|
||||||
|
u32 AX0 = _RealSize;
|
||||||
// TODO: De-Ugly
|
|
||||||
if (PB.Format == 0x21) // Resampled
|
if (PB.RemLength < _RealSize)
|
||||||
samples_to_read = (((PB.CurSampleFrac + (PB.RatioInt * 0x50)) << 4) & 0xFFFF0000) >> 8;
|
|
||||||
else if (PB.Format == 0x20) // Unsampled
|
|
||||||
samples_to_read = 0x50;
|
|
||||||
|
|
||||||
// End of sound
|
|
||||||
if (((PB.raw[0x3a] << 16) | PB.raw[0x3b]) <= samples_to_read)
|
|
||||||
{
|
{
|
||||||
PB.KeyOff = 1;
|
WARN_LOG(VIDEO, "Raw: END");
|
||||||
|
// Let's ignore this entire case since it doesn't seem to happen
|
||||||
|
// in Zelda, since Length is set to 0xF0000000
|
||||||
|
// blah
|
||||||
|
// blah
|
||||||
|
// readaudio
|
||||||
|
// blah
|
||||||
PB.RemLength = 0;
|
PB.RemLength = 0;
|
||||||
|
PB.KeyOff = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PB.RemLength -= _RealSize;
|
||||||
|
|
||||||
|
u64 ACC0 = (u32)(PB.raw[0x8a ^ 1] << 16); // 0x8a 0ad5, yes it loads a, not b
|
||||||
|
u64 ACC1 = (u32)(PB.raw[0x34 ^ 1] << 16); // 0x34
|
||||||
|
|
||||||
|
// ERROR_LOG(DSPHLE, "%08x %08x", (u32)ACC0, (u32)ACC1);
|
||||||
|
|
||||||
|
ACC0 -= ACC1;
|
||||||
|
|
||||||
|
PB.Unk36[0] = ACC0 >> 16;
|
||||||
|
|
||||||
|
// This subtract does really not make much sense at all.
|
||||||
|
ACC0 -= AX0 << 16;
|
||||||
|
|
||||||
|
if ((s64)ACC0 < 0)
|
||||||
|
{
|
||||||
|
// There's something wrong with this looping code.
|
||||||
|
|
||||||
|
// ERROR_LOG(DSPHLE, "Raw loop: ReadAudio size = %04x 34:%04x %08x", PB.Unk36[0], PB.raw[0x34 ^ 1], (int)ACC0);
|
||||||
|
Decoder21_ReadAudio(PB, PB.Unk36[0], _Buffer);
|
||||||
|
|
||||||
|
u32 ACC0 = _Size << 16;
|
||||||
|
ACC0 -= PB.Unk36[0] << 16;
|
||||||
|
|
||||||
|
PB.raw[0x34 ^ 1] = 0;
|
||||||
|
|
||||||
|
PB.StartAddr = PB.LoopStartPos;
|
||||||
|
|
||||||
|
Decoder21_ReadAudio(PB, ACC0 >> 16, _Buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PB.NeedsReset != 0)
|
Decoder21_ReadAudio(PB, _RealSize, _Buffer);
|
||||||
{
|
|
||||||
PB.CurBlock = 0x00;
|
|
||||||
|
|
||||||
// Length in samples.
|
|
||||||
PB.RemLength = PB.Length;
|
|
||||||
|
|
||||||
// Copy ARAM addr from r to rw area.
|
|
||||||
PB.CurAddr = PB.StartAddr;
|
|
||||||
PB.ReachedEnd = 0;
|
|
||||||
PB.CurSampleFrac = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PB.KeyOff != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u8 *source = g_dspInitialize.pGetMemoryPointer(0x80000000);
|
|
||||||
u32 ram_mask = 0x1ffffff;
|
|
||||||
restart:
|
|
||||||
if (PB.ReachedEnd)
|
|
||||||
{
|
|
||||||
PB.ReachedEnd = 0;
|
|
||||||
|
|
||||||
// HACK: Looping doesn't work.
|
|
||||||
if (PB.RepeatMode == 0)
|
|
||||||
{
|
|
||||||
PB.KeyOff = 1;
|
|
||||||
PB.RemLength = 0;
|
|
||||||
PB.CurAddr = PB.StartAddr + PB.RestartPos + PB.Length;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// This needs adjustment. It was just copied from PCM16.
|
|
||||||
PB.RestartPos = PB.LoopStartPos;
|
|
||||||
PB.RemLength = PB.Length - PB.RestartPos;
|
|
||||||
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 prev_addr = PB.CurAddr;
|
|
||||||
|
|
||||||
const u16 *src = (u16 *)(source + (PB.CurAddr & ram_mask));
|
|
||||||
|
|
||||||
s64 TrueSamplePosition = PB.CurSampleFrac; //(s64)(PB.Length - PB.RemLength) << 16;
|
|
||||||
//TrueSamplePosition += PB.CurSampleFrac;
|
|
||||||
s64 delta = ratio >> 16; // 0x100000000ULL;
|
|
||||||
int sampleCount = 0, realSample = 0;
|
|
||||||
while (sampleCount < _Size)
|
|
||||||
{
|
|
||||||
_Buffer[sampleCount] = realSample >> 3;
|
|
||||||
|
|
||||||
sampleCount++;
|
|
||||||
int SamplePosition = TrueSamplePosition >> 16;
|
|
||||||
TrueSamplePosition += delta;
|
|
||||||
int TargetPosition = TrueSamplePosition >> 16;
|
|
||||||
// Decode forwards...
|
|
||||||
while (SamplePosition < TargetPosition)
|
|
||||||
{
|
|
||||||
SamplePosition++;
|
|
||||||
realSample = Common::swap16(*src++);
|
|
||||||
PB.CurAddr += 2;
|
|
||||||
PB.RemLength--;
|
|
||||||
if (PB.RemLength == 0)
|
|
||||||
{
|
|
||||||
PB.ReachedEnd = 1;
|
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PB.NeedsReset = 0;
|
|
||||||
PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Decoder21_ReadAudio(ZeldaVoicePB &PB, int size, s16 *_Buffer)
|
||||||
|
{
|
||||||
|
// 0af6
|
||||||
|
if (!size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// 0afa
|
||||||
|
u32 AX1 = (PB.RestartPos >> 16) & 1; // PB.raw[0x34], except that it's part of a dword
|
||||||
|
// 0b00 - Eh, WTF.
|
||||||
|
u32 ACC0 = PB.StartAddr + ((PB.RestartPos >> 16) << 1) - 2*AX1;
|
||||||
|
u32 ACC1 = (size << 16) + 0x20000;
|
||||||
|
// All this trickery, and more, seems to be to align the DMA, which
|
||||||
|
// we really don't care about. So let's skip it. See the #else.
|
||||||
|
|
||||||
|
#else
|
||||||
|
// ERROR_LOG(DSPHLE, "ReadAudio: %08x %08x", PB.StartAddr, PB.raw[0x34 ^ 1]);
|
||||||
|
u32 ACC0 = PB.StartAddr + (PB.raw[0x34 ^ 1] << 1);
|
||||||
|
u32 ACC1 = (size << 16);
|
||||||
|
#endif
|
||||||
|
// ACC0 is the address
|
||||||
|
// ACC1 is the read size
|
||||||
|
|
||||||
|
const u32 ram_mask = 0x1FFFFFF;
|
||||||
|
const u8 *source = g_dspInitialize.pGetMemoryPointer(0x80000000);
|
||||||
|
const u16 *src = (u16 *)(source + (ACC0 & ram_mask));
|
||||||
|
|
||||||
|
for (int i = 0; i < (ACC1 >> 16); i++) {
|
||||||
|
_Buffer[i] = Common::swap16(src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
PB.raw[0x34 ^ 1] += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _RightBuffer, int _Size)
|
void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _RightBuffer, int _Size)
|
||||||
{
|
{
|
||||||
if (PB.IsBlank)
|
if (PB.IsBlank)
|
||||||
@ -428,7 +426,7 @@ void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _Righ
|
|||||||
Resample(PB, _Size, m_ResampleBuffer + 4, m_VoiceBuffer, true);
|
Resample(PB, _Size, m_ResampleBuffer + 4, m_VoiceBuffer, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0008: // Likely PCM8 - normal PCM 8-bit audio. Used in Mario Kart DD.
|
case 0x0008: // Likely PCM8 - normal PCM 8-bit audio. Used in Mario Kart DD + very little in Zelda WW.
|
||||||
WARN_LOG(DSPHLE, "Unimplemented MixAddVoice format in zelda %04x", PB.Format);
|
WARN_LOG(DSPHLE, "Unimplemented MixAddVoice format in zelda %04x", PB.Format);
|
||||||
memset(m_ResampleBuffer + 4, 0, _Size * sizeof(s32));
|
memset(m_ResampleBuffer + 4, 0, _Size * sizeof(s32));
|
||||||
Resample(PB, _Size, m_ResampleBuffer + 4, m_VoiceBuffer);
|
Resample(PB, _Size, m_ResampleBuffer + 4, m_VoiceBuffer);
|
||||||
@ -444,28 +442,16 @@ void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _Righ
|
|||||||
// to the output buffer. However, (if we ever see this sound type), we'll
|
// to the output buffer. However, (if we ever see this sound type), we'll
|
||||||
// have to resample anyway since we're running at a different sample rate.
|
// have to resample anyway since we're running at a different sample rate.
|
||||||
|
|
||||||
#if 0 // To hear something weird in ZWW, turn this on.
|
|
||||||
// Caution: Use at your own risk. Sounds awful :)
|
// Caution: Use at your own risk. Sounds awful :)
|
||||||
RenderVoice_Raw(PB, m_ResampleBuffer + 4, _Size);
|
RenderVoice_Raw(PB, m_ResampleBuffer + 4, _Size);
|
||||||
#else
|
Resample(PB, _Size, m_ResampleBuffer + 4, m_VoiceBuffer, true);
|
||||||
// This is what 0x20 and 0x21 do on end of voice
|
|
||||||
PB.RemLength = 0;
|
|
||||||
PB.KeyOff = 1;
|
|
||||||
#endif
|
|
||||||
Resample(PB, _Size, m_ResampleBuffer + 4, m_VoiceBuffer);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0021:
|
case 0x0021:
|
||||||
// Raw sound from RAM. Important for Zelda WW. Really need to implement - missing it causes hangs.
|
// Raw sound from RAM. Important for Zelda WW. Really need to implement - missing it causes hangs.
|
||||||
#if 0 // To hear something weird in ZWW, turn this on.
|
|
||||||
// Caution: Use at your own risk. Sounds awful :)
|
// Caution: Use at your own risk. Sounds awful :)
|
||||||
RenderVoice_Raw(PB, m_ResampleBuffer + 4, _Size);
|
RenderVoice_Raw(PB, m_ResampleBuffer + 4, _Size);
|
||||||
#else
|
Resample(PB, _Size, m_ResampleBuffer + 4, m_VoiceBuffer, true);
|
||||||
// This is what 0x20 and 0x21 do on end of voice
|
|
||||||
PB.RemLength = 0;
|
|
||||||
PB.KeyOff = 1;
|
|
||||||
#endif
|
|
||||||
Resample(PB, _Size, m_ResampleBuffer + 4, m_VoiceBuffer);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Reference in New Issue
Block a user