Merge pull request #5211 from MerryMage/ax

AX: Implement loop_counter and support UCodes without LPF
This commit is contained in:
Pierre Bourdon 2017-04-08 17:22:47 +02:00 committed by GitHub
commit e863604b7e
6 changed files with 68 additions and 27 deletions

View File

@ -3,17 +3,11 @@
[Core] [Core]
# Values set here will override the main Dolphin settings. # Values set here will override the main Dolphin settings.
MMU = 1 MMU = 1
# LLE audio enabled by default for a listenable output
DSPHLE = False
[DSP]
# Ensure the LLE recompiler gets selected and not interpreter.
EnableJIT = True
[EmuState] [EmuState]
# The Emulation State. 1 is worst, 5 is best, 0 is not set. # The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4 EmulationStateId = 4
EmulationIssues = Needs LLE audio for proper sound. EmulationIssues =
[OnLoad] [OnLoad]
# Add memory patches to be loaded once on boot here. # Add memory patches to be loaded once on boot here.

View File

@ -3,16 +3,10 @@
[Core] [Core]
# Values set here will override the main Dolphin settings. # Values set here will override the main Dolphin settings.
MMU = 1 MMU = 1
# LLE audio enabled by default for a listenable output
DSPHLE = False
[DSP]
# Ensure the LLE recompiler gets selected and not interpreter.
EnableJIT = True
[EmuState] [EmuState]
# The Emulation State. 1 is worst, 5 is best, 0 is not set. # The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues = Needs LLE audio for proper sound. EmulationIssues =
EmulationStateId = 4 EmulationStateId = 4
[OnLoad] [OnLoad]

View File

@ -422,7 +422,7 @@ void AXUCode::ProcessPBList(u32 pb_addr)
m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left, m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left,
m_samples_auxB_right, m_samples_auxB_surround}}; m_samples_auxB_right, m_samples_auxB_surround}};
ReadPB(pb_addr, pb); ReadPB(pb_addr, pb, m_crc);
u32 updates_addr = HILO_TO_32(pb.updates.data); u32 updates_addr = HILO_TO_32(pb.updates.data);
u16* updates = (u16*)HLEMemory_Get_Pointer(updates_addr); u16* updates = (u16*)HLEMemory_Get_Pointer(updates_addr);
@ -439,7 +439,7 @@ void AXUCode::ProcessPBList(u32 pb_addr)
buffers.ptrs[i] += spms; buffers.ptrs[i] += spms;
} }
WritePB(pb_addr, pb); WritePB(pb_addr, pb, m_crc);
pb_addr = HILO_TO_32(pb.next_pb); pb_addr = HILO_TO_32(pb.next_pb);
} }
} }

View File

@ -252,9 +252,10 @@ struct AXPB
PBADPCMInfo adpcm; PBADPCMInfo adpcm;
PBSampleRateConverter src; PBSampleRateConverter src;
PBADPCMLoopInfo adpcm_loop_info; PBADPCMLoopInfo adpcm_loop_info;
PBLowPassFilter lpf; PBLowPassFilter lpf; // Skipped when writing to/reading from MRAM/ARAM for certain AX UCodes
u16 loop_counter;
u16 padding[25]; u16 padding[24];
}; };
struct PBBiquadFilter struct PBBiquadFilter

View File

@ -80,19 +80,64 @@ union AXBuffers
#endif #endif
}; };
// Determines if this version of the UCode has a PBLowPassFilter in its AXPB layout.
bool HasLpf(u32 crc)
{
switch (crc)
{
case 0x4E8A8B21:
return false;
default:
return true;
}
}
// Read a PB from MRAM/ARAM // Read a PB from MRAM/ARAM
void ReadPB(u32 addr, PB_TYPE& pb) void ReadPB(u32 addr, PB_TYPE& pb, u32 crc)
{
if (HasLpf(crc))
{ {
u16* dst = (u16*)&pb; u16* dst = (u16*)&pb;
Memory::CopyFromEmuSwapped<u16>(dst, addr, sizeof(pb)); Memory::CopyFromEmuSwapped<u16>(dst, addr, sizeof(pb));
} }
else
{
// The below is a terrible hack in order to support two different AXPB layouts.
// We skip lpf in this layout.
char* dst = (char*)&pb;
constexpr size_t lpf_off = offsetof(AXPB, lpf);
constexpr size_t lc_off = offsetof(AXPB, loop_counter);
Memory::CopyFromEmuSwapped<u16>((u16*)dst, addr, lpf_off);
memset(dst + lpf_off, 0, lc_off - lpf_off);
Memory::CopyFromEmuSwapped<u16>((u16*)(dst + lc_off), addr + lpf_off, sizeof(pb) - lc_off);
}
}
// Write a PB back to MRAM/ARAM // Write a PB back to MRAM/ARAM
void WritePB(u32 addr, const PB_TYPE& pb) void WritePB(u32 addr, const PB_TYPE& pb, u32 crc)
{
if (HasLpf(crc))
{ {
const u16* src = (const u16*)&pb; const u16* src = (const u16*)&pb;
Memory::CopyToEmuSwapped<u16>(addr, src, sizeof(pb)); Memory::CopyToEmuSwapped<u16>(addr, src, sizeof(pb));
} }
else
{
// The below is a terrible hack in order to support two different AXPB layouts.
// We skip lpf in this layout.
const char* src = (const char*)&pb;
constexpr size_t lpf_off = offsetof(AXPB, lpf);
constexpr size_t lc_off = offsetof(AXPB, loop_counter);
Memory::CopyToEmuSwapped<u16>(addr, (const u16*)src, lpf_off);
Memory::CopyToEmuSwapped<u16>(addr + lpf_off, (const u16*)(src + lc_off), sizeof(pb) - lc_off);
}
}
#if 0 #if 0
// Dump the value of a PB for debugging // Dump the value of a PB for debugging
@ -234,6 +279,13 @@ u16 AcceleratorGetSample()
acc_pb->adpcm.yn1 = acc_pb->adpcm_loop_info.yn1; acc_pb->adpcm.yn1 = acc_pb->adpcm_loop_info.yn1;
acc_pb->adpcm.yn2 = acc_pb->adpcm_loop_info.yn2; acc_pb->adpcm.yn2 = acc_pb->adpcm_loop_info.yn2;
} }
#ifdef AX_GC
else
{
// If we're streaming, increment the loop counter.
acc_pb->loop_counter++;
}
#endif
} }
else else
{ {

View File

@ -451,7 +451,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
m_samples_aux1, m_samples_wm2, m_samples_aux2, m_samples_aux1, m_samples_wm2, m_samples_aux2,
m_samples_wm3, m_samples_aux3}}; m_samples_wm3, m_samples_aux3}};
ReadPB(pb_addr, pb); ReadPB(pb_addr, pb, m_crc);
u16 num_updates[3]; u16 num_updates[3];
u16 updates[1024]; u16 updates[1024];
@ -476,7 +476,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
m_coeffs_available ? m_coeffs : nullptr); m_coeffs_available ? m_coeffs : nullptr);
} }
WritePB(pb_addr, pb); WritePB(pb_addr, pb, m_crc);
pb_addr = HILO_TO_32(pb.next_pb); pb_addr = HILO_TO_32(pb.next_pb);
} }
} }