diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index 7bca18bdd8..b8f01530fc 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -243,8 +243,7 @@ static u32 _sceSasCore(u32 core, u32 outAddr) { __SasEnqueueMix(outAddr); - // Actual delay time seems to between 240 and 1000 us, based on grain and possibly other factors. - return hleLogSuccessI(SCESAS, hleDelayResult(0, "sas core", 240)); + return hleLogSuccessI(SCESAS, hleDelayResult(0, "sas core", sas->EstimateMixUs())); } // Another way of running the mixer, the inoutAddr should be both input and output @@ -260,8 +259,7 @@ static u32 _sceSasCoreWithMix(u32 core, u32 inoutAddr, int leftVolume, int right __SasEnqueueMix(inoutAddr, inoutAddr, leftVolume, rightVolume); - // Actual delay time seems to between 240 and 1000 us, based on grain and possibly other factors. - return hleLogSuccessI(SCESAS, hleDelayResult(0, "sas core", 240)); + return hleLogSuccessI(SCESAS, hleDelayResult(0, "sas core", sas->EstimateMixUs())); } static u32 sceSasSetVoice(u32 core, int voiceNum, u32 vagAddr, int size, int loop) { diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 1d383a369a..78baaf39ee 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -408,6 +408,20 @@ void SasInstance::SetGrainSize(int newGrainSize) { resampleBuffer = new s16[grainSize * 4 + 3]; } +int SasInstance::EstimateMixUs() { + int voicesPlayingCount = 0; + + for (int v = 0; v < PSP_SAS_VOICES_MAX; v++) { + SasVoice &voice = voices[v]; + if (!voice.playing || voice.paused) + continue; + voicesPlayingCount++; + } + + // Each voice costs extra time, and each byte of grain costs extra time. + return 20 + voicesPlayingCount * 68 + (grainSize * 60) / 100; +} + void SasVoice::ReadSamples(s16 *output, int numSamples) { // Read N samples into the resample buffer. Could do either PCM or VAG here. switch (type) { diff --git a/Core/HW/SasAudio.h b/Core/HW/SasAudio.h index 07257027ff..fd4283e2f6 100644 --- a/Core/HW/SasAudio.h +++ b/Core/HW/SasAudio.h @@ -278,6 +278,7 @@ public: void ClearGrainSize(); void SetGrainSize(int newGrainSize); int GetGrainSize() const { return grainSize; } + int EstimateMixUs(); int maxVoices; int sampleRate;