mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-31 10:09:36 -06:00
Added the Zelda UCode preliminary synthesizer. It's far from perfect, but it sounds like the exact pitch it should synth. I'd be glad if someone finished it.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3630 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -23,6 +23,7 @@ files = [
|
||||
'UCodes/UCode_Zelda.cpp',
|
||||
'UCodes/UCode_Zelda_ADPCM.cpp',
|
||||
'UCodes/UCode_Zelda_Voice.cpp',
|
||||
'UCodes/UCode_Zelda_Synth.cpp',
|
||||
]
|
||||
|
||||
dspenv = env.Clone()
|
||||
|
@ -25,19 +25,75 @@
|
||||
|
||||
void CUCode_Zelda::MixAddSynth_Waveform(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
||||
{
|
||||
int mask = PB.Format ? 3 : 1;
|
||||
|
||||
for (int i = 0; i < _Size; i++)
|
||||
{
|
||||
s16 sample = (i & mask) ? 0xc000 : 0x4000;
|
||||
|
||||
_Buffer[i++] = (s32)sample;
|
||||
}
|
||||
float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
|
||||
u32 _ratio = (((PB.RatioInt * 80) + PB.RatioFrac) << 4) & 0xFFFF0000;
|
||||
u64 ratio = (u64)(((_ratio / 80) << 16) * ratioFactor);
|
||||
int mask = PB.Format ? 3 : 1, shift = PB.Format ? 2 : 1;
|
||||
|
||||
u32 pos[2] = {0, 0};
|
||||
int i = 0;
|
||||
|
||||
if (PB.KeyOff != 0)
|
||||
return;
|
||||
|
||||
if (PB.NeedsReset)
|
||||
{
|
||||
PB.RemLength = PB.Length - PB.RestartPos;
|
||||
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
|
||||
PB.ReachedEnd = 0;
|
||||
}
|
||||
|
||||
_lRestart:
|
||||
if (PB.ReachedEnd)
|
||||
{
|
||||
PB.ReachedEnd = 0;
|
||||
|
||||
if (PB.RepeatMode == 0)
|
||||
{
|
||||
PB.KeyOff = 1;
|
||||
PB.RemLength = 0;
|
||||
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1) + PB.Length;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PB.RestartPos = PB.LoopStartPos;
|
||||
PB.RemLength = PB.Length - PB.RestartPos;
|
||||
PB.CurAddr = PB.StartAddr + (PB.RestartPos << 1);
|
||||
pos[1] = 0; pos[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < _Size;)
|
||||
{
|
||||
s16 sample = ((pos[1] & mask) == mask) ? 0xc000 : 0x4000;
|
||||
|
||||
_Buffer[i++] = (s32)sample;
|
||||
|
||||
(*(u64*)&pos) += ratio;
|
||||
if ((pos[1] + ((PB.CurAddr - PB.StartAddr) >> 1)) >= PB.Length)
|
||||
{
|
||||
PB.ReachedEnd = 1;
|
||||
goto _lRestart;
|
||||
}
|
||||
}
|
||||
|
||||
if (PB.RemLength < pos[1])
|
||||
{
|
||||
PB.RemLength = 0;
|
||||
PB.ReachedEnd = 1;
|
||||
}
|
||||
else
|
||||
PB.RemLength -= pos[1];
|
||||
|
||||
PB.CurAddr += pos[1] << 1;
|
||||
// There should be a position fraction as well.
|
||||
}
|
||||
|
||||
|
||||
void CUCode_Zelda::MixAddSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
||||
{
|
||||
// TODO: Header, footer and cases this synth actually happens
|
||||
for (int i = 0; i < _Size; i++)
|
||||
_Buffer[i++] = (s32)PB.RatioInt;
|
||||
}
|
||||
|
@ -281,20 +281,22 @@ void CUCode_Zelda::MixAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _RightBu
|
||||
{
|
||||
switch (PB.Format)
|
||||
{
|
||||
|
||||
// Synthesized sounds
|
||||
case 0x0000:
|
||||
case 0x0001: // Used for "Denied" sound in Zelda
|
||||
//MixAddSynth_Waveform(PB, m_TempBuffer, _Size);
|
||||
break;
|
||||
case 0x0000: // Example: Magic meter filling up in ZWW
|
||||
case 0x0001: // Example: "Denied" sound when trying to pull out a sword
|
||||
// indoors in ZWW
|
||||
MixAddSynth_Waveform(PB, m_TempBuffer, _Size);
|
||||
break;
|
||||
|
||||
case 0x0006:
|
||||
//MixAddSynth_Waveform(PB, m_TempBuffer, _Size);
|
||||
break;
|
||||
WARN_LOG(DSPHLE, "Synthesizing 0x0006 (constant sound)");
|
||||
MixAddSynth_Constant(PB, m_TempBuffer, _Size);
|
||||
break;
|
||||
|
||||
// These are more "synth" formats - square wave, saw wave etc.
|
||||
// These are more "synth" formats - square wave, saw wave etc.
|
||||
case 0x0002:
|
||||
return;
|
||||
WARN_LOG(DSPHLE, "Synthesizing 0x0002");
|
||||
break;
|
||||
|
||||
|
||||
// AFC formats
|
||||
|
Reference in New Issue
Block a user