TEMP: Throttle core0 SPU block transfers when noise is enabled on core1.

This is obviously not going to be merged.
This commit is contained in:
Jean-Philip Desjardins 2021-07-07 13:54:42 -04:00
parent 075b519c52
commit 197e45ea25
3 changed files with 87 additions and 12 deletions

View file

@ -200,6 +200,10 @@ void CSpuBase::Reset()
m_blockReader.Reset(); m_blockReader.Reset();
m_soundInputDataAddr = (m_spuNumber == 0) ? SOUND_INPUT_DATA_CORE0_BASE : SOUND_INPUT_DATA_CORE1_BASE; m_soundInputDataAddr = (m_spuNumber == 0) ? SOUND_INPUT_DATA_CORE0_BASE : SOUND_INPUT_DATA_CORE1_BASE;
m_blockWritePtr = 0; m_blockWritePtr = 0;
m_measureMode = false;
m_noiseValue = 0;
m_noiseUpdateTime = 0;
} }
void CSpuBase::LoadState(Framework::CZipArchiveReader& archive) void CSpuBase::LoadState(Framework::CZipArchiveReader& archive)
@ -385,12 +389,30 @@ void CSpuBase::SetChannelOnHi(uint16 value)
void CSpuBase::SetChannelNoiseLo(uint16 value) void CSpuBase::SetChannelNoiseLo(uint16 value)
{ {
uint32 prevValue = m_channelNoise.f;
m_channelNoise.h0 = value; m_channelNoise.h0 = value;
if(prevValue != m_channelNoise.f)
{
if(OnNoiseStatusChanged)
{
OnNoiseStatusChanged(m_channelNoise.f);
}
}
m_noiseValue = 0;
m_noiseUpdateTime = 0;
} }
void CSpuBase::SetChannelNoiseHi(uint16 value) void CSpuBase::SetChannelNoiseHi(uint16 value)
{ {
uint32 prevValue = m_channelNoise.f;
m_channelNoise.h1 = value; m_channelNoise.h1 = value;
if(prevValue != m_channelNoise.f)
{
if(OnNoiseStatusChanged)
{
OnNoiseStatusChanged(m_channelNoise.f);
}
}
} }
UNION32_16 CSpuBase::GetChannelReverb() const UNION32_16 CSpuBase::GetChannelReverb() const
@ -529,14 +551,24 @@ uint32 CSpuBase::ReceiveDma(uint8* buffer, uint32 blockSize, uint32 blockAmount,
if((m_ctrl & CONTROL_DMA) == CONTROL_DMA_READ) if((m_ctrl & CONTROL_DMA) == CONTROL_DMA_READ)
{ {
//- DMA reads need to be throttled to allow FFX IopSoundDriver to properly synchronize itself //- DMA reads need to be throttled to allow FFX IopSoundDriver to properly synchronize itself
if((m_noiseUpdateTime % 5) == 0)
{
m_noiseValue++;
}
m_noiseUpdateTime++;
blockAmount = std::min<uint32>(blockAmount, 0x10); blockAmount = std::min<uint32>(blockAmount, 0x10);
for(unsigned int i = 0; i < blockAmount; i++) for(unsigned int i = 0; i < blockAmount; i++)
{ {
memcpy(buffer, m_ram + m_transferAddr, blockSize); memcpy(buffer, m_ram + m_transferAddr, blockSize);
buffer[0] = m_noiseValue;
m_transferAddr += blockSize; m_transferAddr += blockSize;
m_transferAddr &= m_ramSize - 1; m_transferAddr &= m_ramSize - 1;
buffer += blockSize; buffer += blockSize;
} }
if(OnReadTransfer)
{
OnReadTransfer();
}
return blockAmount; return blockAmount;
} }
//- Tsugunai needs voice transfers to be throttled because it starts a DMA transfer //- Tsugunai needs voice transfers to be throttled because it starts a DMA transfer
@ -581,6 +613,27 @@ uint32 CSpuBase::ReceiveDma(uint8* buffer, uint32 blockSize, uint32 blockAmount,
} }
} }
void CSpuBase::AdjustBlockBufferSize()
{
if(m_blockWritePtr == SOUND_INPUT_DATA_SIZE)
{
m_blockWritePtr = 0x200;
}
}
void CSpuBase::SetMeasureMode(bool measureMode)
{
m_measureMode = measureMode;
if(m_measureMode)
{
m_blockWritePtr = SOUND_INPUT_DATA_SIZE;
}
else
{
m_blockWritePtr = 0;
}
}
void CSpuBase::WriteWord(uint16 value) void CSpuBase::WriteWord(uint16 value)
{ {
assert((m_transferAddr + 1) < m_ramSize); assert((m_transferAddr + 1) < m_ramSize);
@ -713,21 +766,24 @@ void CSpuBase::Render(int16* samples, unsigned int sampleCount, unsigned int sam
} }
} }
if(!m_blockReader.CanReadSamples() && (m_blockWritePtr == SOUND_INPUT_DATA_SIZE)) if(!m_measureMode)
{ {
//We're ready to consume some data if(!m_blockReader.CanReadSamples() && (m_blockWritePtr == SOUND_INPUT_DATA_SIZE))
m_blockReader.FillBlock(m_ram + m_soundInputDataAddr); {
m_blockWritePtr = 0; //We're ready to consume some data
} m_blockReader.FillBlock(m_ram + m_soundInputDataAddr);
m_blockWritePtr = 0;
}
if(m_blockReader.CanReadSamples()) if(m_blockReader.CanReadSamples())
{ {
int16 sampleL = 0; int16 sampleL = 0;
int16 sampleR = 0; int16 sampleR = 0;
m_blockReader.GetSamples(sampleL, sampleR, sampleRate); m_blockReader.GetSamples(sampleL, sampleR, sampleRate);
MixSamples(sampleL, 0x3FFF, samples + 0); MixSamples(sampleL, 0x3FFF, samples + 0);
MixSamples(sampleR, 0x3FFF, samples + 1); MixSamples(sampleR, 0x3FFF, samples + 1);
}
} }
//Simulate SPU CORE0 writing its output in RAM and check for potential interrupts //Simulate SPU CORE0 writing its output in RAM and check for potential interrupts

View file

@ -222,6 +222,11 @@ namespace Iop
static bool g_reverbParamIsAddress[REVERB_PARAM_COUNT]; static bool g_reverbParamIsAddress[REVERB_PARAM_COUNT];
std::function<void(uint32)> OnNoiseStatusChanged;
std::function<void()> OnReadTransfer;
void SetMeasureMode(bool);
void AdjustBlockBufferSize();
private: private:
enum enum
{ {
@ -358,6 +363,10 @@ namespace Iop
bool m_reverbEnabled; bool m_reverbEnabled;
float m_volumeAdjust; float m_volumeAdjust;
bool m_measureMode = false;
uint32 m_noiseValue = 0;
uint32 m_noiseUpdateTime = 0;
CBlockSampleReader m_blockReader; CBlockSampleReader m_blockReader;
uint32 m_soundInputDataAddr = 0; uint32 m_soundInputDataAddr = 0;
uint32 m_blockWritePtr = 0; uint32 m_blockWritePtr = 0;

View file

@ -81,6 +81,16 @@ CSubSystem::CSubSystem(bool ps2Mode)
m_dmac.SetReceiveFunction(CDmac::CHANNEL_SIO2in, std::bind(&CSio2::ReceiveDmaIn, &m_sio2, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4)); m_dmac.SetReceiveFunction(CDmac::CHANNEL_SIO2in, std::bind(&CSio2::ReceiveDmaIn, &m_sio2, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4));
m_dmac.SetReceiveFunction(CDmac::CHANNEL_SIO2out, std::bind(&CSio2::ReceiveDmaOut, &m_sio2, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4)); m_dmac.SetReceiveFunction(CDmac::CHANNEL_SIO2out, std::bind(&CSio2::ReceiveDmaOut, &m_sio2, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4));
m_spuCore1.OnNoiseStatusChanged =
[&](uint32 value) {
m_spuCore0.SetMeasureMode(value != 0);
};
m_spuCore1.OnReadTransfer =
[&] {
m_spuCore0.AdjustBlockBufferSize();
m_dmac.ResumeDma(Iop::CDmac::CHANNEL_SPU0);
};
SetupPageTable(); SetupPageTable();
} }