Take the size of the audio data into account when checking for the loop address. Fixes the static audio in the FMV of Megaman X Collection, Pac Man World 2, off pitched instruments in Skies of Arcadia and audio desync in the Taiko no Tatsujin series.
Fixes: issue 7154 issue 7222 issue 7280 issue 7457
This commit is contained in:
parent
ea7eee1f58
commit
91a6962565
|
@ -15,7 +15,7 @@ static s16 ADPCM_Step(u32& _rSamplePos)
|
|||
{
|
||||
const s16 *pCoefTable = (const s16 *)&g_dsp.ifx_regs[DSP_COEF_A1_0];
|
||||
|
||||
if (((_rSamplePos) & 15) == 0)
|
||||
if (((_rSamplePos)& 15) == 0)
|
||||
{
|
||||
g_dsp.ifx_regs[DSP_PRED_SCALE] = DSPHost::ReadHostMemory((_rSamplePos & ~15) >> 1);
|
||||
_rSamplePos += 2;
|
||||
|
@ -63,7 +63,7 @@ u16 dsp_read_aram_d3()
|
|||
Address++;
|
||||
break;
|
||||
case 0x6: // u16 reads
|
||||
val = (DSPHost::ReadHostMemory(Address*2) << 8) | DSPHost::ReadHostMemory(Address*2 + 1);
|
||||
val = (DSPHost::ReadHostMemory(Address * 2) << 8) | DSPHost::ReadHostMemory(Address * 2 + 1);
|
||||
Address++;
|
||||
break;
|
||||
default:
|
||||
|
@ -93,8 +93,8 @@ void dsp_write_aram_d3(u16 value)
|
|||
switch (g_dsp.ifx_regs[DSP_FORMAT])
|
||||
{
|
||||
case 0xA: // u16 writes
|
||||
DSPHost::WriteHostMemory(value >> 8, Address*2);
|
||||
DSPHost::WriteHostMemory(value & 0xFF, Address*2 + 1);
|
||||
DSPHost::WriteHostMemory(value >> 8, Address * 2);
|
||||
DSPHost::WriteHostMemory(value & 0xFF, Address * 2 + 1);
|
||||
Address++;
|
||||
break;
|
||||
default:
|
||||
|
@ -111,6 +111,7 @@ u16 dsp_read_accelerator()
|
|||
const u32 EndAddress = (g_dsp.ifx_regs[DSP_ACEAH] << 16) | g_dsp.ifx_regs[DSP_ACEAL];
|
||||
u32 Address = (g_dsp.ifx_regs[DSP_ACCAH] << 16) | g_dsp.ifx_regs[DSP_ACCAL];
|
||||
u16 val;
|
||||
u8 step_size_bytes = 0;
|
||||
|
||||
// let's do the "hardware" decode DSP_FORMAT is interesting - the Zelda
|
||||
// ucode seems to indicate that the bottom two bits specify the "read size"
|
||||
|
@ -122,21 +123,25 @@ u16 dsp_read_accelerator()
|
|||
{
|
||||
case 0x00: // ADPCM audio
|
||||
val = ADPCM_Step(Address);
|
||||
step_size_bytes = 2;
|
||||
break;
|
||||
case 0x0A: // 16-bit PCM audio
|
||||
val = (DSPHost::ReadHostMemory(Address*2) << 8) | DSPHost::ReadHostMemory(Address*2 + 1);
|
||||
val = (DSPHost::ReadHostMemory(Address * 2) << 8) | DSPHost::ReadHostMemory(Address * 2 + 1);
|
||||
g_dsp.ifx_regs[DSP_YN2] = g_dsp.ifx_regs[DSP_YN1];
|
||||
g_dsp.ifx_regs[DSP_YN1] = val;
|
||||
step_size_bytes = 2;
|
||||
Address++;
|
||||
break;
|
||||
case 0x19: // 8-bit PCM audio
|
||||
val = DSPHost::ReadHostMemory(Address) << 8;
|
||||
g_dsp.ifx_regs[DSP_YN2] = g_dsp.ifx_regs[DSP_YN1];
|
||||
g_dsp.ifx_regs[DSP_YN1] = val;
|
||||
step_size_bytes = 1;
|
||||
Address++;
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(DSPLLE, "dsp_read_accelerator() - unknown format 0x%x", g_dsp.ifx_regs[DSP_FORMAT]);
|
||||
step_size_bytes = 1;
|
||||
Address++;
|
||||
val = 0;
|
||||
break;
|
||||
|
@ -151,7 +156,7 @@ u16 dsp_read_accelerator()
|
|||
// Somehow, YN1 and YN2 must be initialized with their "loop" values,
|
||||
// so yeah, it seems likely that we should raise an exception to let
|
||||
// the DSP program do that, at least if DSP_FORMAT == 0x0A.
|
||||
if ((Address & ~1) == (EndAddress & ~1))
|
||||
if (Address == (EndAddress + step_size_bytes - 1))
|
||||
{
|
||||
// Set address back to start address.
|
||||
Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL];
|
||||
|
|
|
@ -149,12 +149,17 @@ void AcceleratorSetup(PB_TYPE* pb, u32* cur_addr)
|
|||
u16 AcceleratorGetSample()
|
||||
{
|
||||
u16 ret;
|
||||
u8 step_size_bytes = 2;
|
||||
|
||||
// 8-bit PCM audio uses 1 byte per sample/sample block, not 2 like other formats.
|
||||
if (acc_pb->audio_addr.sample_format == 0x19)
|
||||
step_size_bytes = 1;
|
||||
|
||||
// Have we reached the end address?
|
||||
//
|
||||
// On real hardware, this would raise an interrupt that is handled by the
|
||||
// UCode. We simulate what this interrupt does here.
|
||||
if ((*acc_cur_addr & ~1) == (acc_end_addr & ~1))
|
||||
if (*acc_cur_addr == (acc_end_addr + step_size_bytes - 1))
|
||||
{
|
||||
// loop back to loop_addr.
|
||||
*acc_cur_addr = acc_loop_addr;
|
||||
|
|
Loading…
Reference in New Issue