From 1a1b89e7e87818d51a7b33d19245174ecdd78bb2 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 29 Aug 2020 13:24:39 +0200 Subject: [PATCH 1/2] AudioInterface: Use 32029/48043 Hz in more places In particular, I wanted to do change this in AudioInterface::Init so that dumped GC audio doesn't need to have a file split (changing from 32000 Hz to 32029 Hz) when the emulated software initializes the AI registers. I've also made the same change to DI's DTK code. --- Source/Core/Core/HW/AudioInterface.cpp | 24 ++++++++++++++---------- Source/Core/Core/HW/AudioInterface.h | 3 +++ Source/Core/Core/HW/DVD/DVDInterface.cpp | 13 ++++++++----- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/Source/Core/Core/HW/AudioInterface.cpp b/Source/Core/Core/HW/AudioInterface.cpp index eb6dc2a6c0..0f9afc57c9 100644 --- a/Source/Core/Core/HW/AudioInterface.cpp +++ b/Source/Core/Core/HW/AudioInterface.cpp @@ -149,8 +149,8 @@ void Init() s_last_cpu_time = 0; s_cpu_cycles_per_sample = 0xFFFFFFFFFFFULL; - s_ais_sample_rate = 48000; - s_aid_sample_rate = 32000; + s_ais_sample_rate = Get48KHzSampleRate(); + s_aid_sample_rate = Get32KHzSampleRate(); event_type_ai = CoreTiming::RegisterEvent("AICallback", Update); } @@ -184,10 +184,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) // AISFR rates below are intentionally inverted wrt yagcd DEBUG_LOG(AUDIO_INTERFACE, "Change AISFR to %s", tmp_ai_ctrl.AISFR ? "48khz" : "32khz"); s_control.AISFR = tmp_ai_ctrl.AISFR; - if (SConfig::GetInstance().bWii) - s_ais_sample_rate = tmp_ai_ctrl.AISFR ? 48000 : 32000; - else - s_ais_sample_rate = tmp_ai_ctrl.AISFR ? 48043 : 32029; + s_ais_sample_rate = tmp_ai_ctrl.AISFR ? Get48KHzSampleRate() : Get32KHzSampleRate(); g_sound_stream->GetMixer()->SetStreamInputSampleRate(s_ais_sample_rate); s_cpu_cycles_per_sample = SystemTimers::GetTicksPerSecond() / s_ais_sample_rate; } @@ -196,10 +193,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) { DEBUG_LOG(AUDIO_INTERFACE, "Change AIDFR to %s", tmp_ai_ctrl.AIDFR ? "32khz" : "48khz"); s_control.AIDFR = tmp_ai_ctrl.AIDFR; - if (SConfig::GetInstance().bWii) - s_aid_sample_rate = tmp_ai_ctrl.AIDFR ? 32000 : 48000; - else - s_aid_sample_rate = tmp_ai_ctrl.AIDFR ? 32029 : 48043; + s_aid_sample_rate = tmp_ai_ctrl.AIDFR ? Get32KHzSampleRate() : Get48KHzSampleRate(); g_sound_stream->GetMixer()->SetDMAInputSampleRate(s_aid_sample_rate); } @@ -304,6 +298,16 @@ unsigned int GetAIDSampleRate() return s_aid_sample_rate; } +u32 Get32KHzSampleRate() +{ + return SConfig::GetInstance().bWii ? 32000 : 32029; +} + +u32 Get48KHzSampleRate() +{ + return SConfig::GetInstance().bWii ? 48000 : 48043; +} + static void Update(u64 userdata, s64 cycles_late) { if (s_control.PSTAT) diff --git a/Source/Core/Core/HW/AudioInterface.h b/Source/Core/Core/HW/AudioInterface.h index 092399d67c..2ffbaeadf7 100644 --- a/Source/Core/Core/HW/AudioInterface.h +++ b/Source/Core/Core/HW/AudioInterface.h @@ -26,6 +26,9 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base); // Get the audio rates (48000 or 32000 only) unsigned int GetAIDSampleRate(); +u32 Get32KHzSampleRate(); +u32 Get48KHzSampleRate(); + void GenerateAISInterrupt(); } // namespace AudioInterface diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index 9d5afafd5c..5dddd88f3d 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -294,8 +294,11 @@ static u32 AdvanceDTK(u32 maximum_samples, u32* samples_to_process) static void DTKStreamingCallback(DIInterruptType interrupt_type, const std::vector& audio_data, s64 cycles_late) { + // TODO: Should we use the configured AIS sample rate instead of a fixed 48 KHz? + const u32 sample_rate = AudioInterface::Get48KHzSampleRate(); + // Determine which audio data to read next. - static const int MAXIMUM_SAMPLES = 48000 / 2000 * 7; // 3.5ms of 48kHz samples + const u32 maximum_samples = sample_rate / 2000 * 7; // 3.5 ms of samples u64 read_offset = 0; u32 read_length = 0; @@ -309,22 +312,22 @@ static void DTKStreamingCallback(DIInterruptType interrupt_type, const std::vect if (s_stream && AudioInterface::IsPlaying()) { read_offset = s_audio_position; - read_length = AdvanceDTK(MAXIMUM_SAMPLES, &s_pending_samples); + read_length = AdvanceDTK(maximum_samples, &s_pending_samples); } else { read_length = 0; - s_pending_samples = MAXIMUM_SAMPLES; + s_pending_samples = maximum_samples; } } else { read_length = 0; - s_pending_samples = MAXIMUM_SAMPLES; + s_pending_samples = maximum_samples; } // Read the next chunk of audio data asynchronously. - s64 ticks_to_dtk = SystemTimers::GetTicksPerSecond() * s64(s_pending_samples) / 48000; + s64 ticks_to_dtk = SystemTimers::GetTicksPerSecond() * s64(s_pending_samples) / sample_rate; ticks_to_dtk -= cycles_late; if (read_length > 0) { From bd44106fec950a962fa6150e0b76539504e89476 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 29 Aug 2020 16:42:57 +0200 Subject: [PATCH 2/2] AudioCommon: Get initial sample rates from AudioInterface --- Source/Core/AudioCommon/AudioCommon.cpp | 7 +++++++ Source/Core/Core/HW/AudioInterface.cpp | 7 ++++++- Source/Core/Core/HW/AudioInterface.h | 3 ++- Source/Core/Core/HW/DVD/DVDInterface.cpp | 3 ++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Source/Core/AudioCommon/AudioCommon.cpp b/Source/Core/AudioCommon/AudioCommon.cpp index 467406dd9c..1330785ac8 100644 --- a/Source/Core/AudioCommon/AudioCommon.cpp +++ b/Source/Core/AudioCommon/AudioCommon.cpp @@ -15,6 +15,7 @@ #include "Common/FileUtil.h" #include "Common/Logging/Log.h" #include "Core/ConfigManager.h" +#include "Core/HW/AudioInterface.h" // This shouldn't be a global, at least not here. std::unique_ptr g_sound_stream; @@ -67,6 +68,12 @@ void InitSoundStream() g_sound_stream->Init(); } + // Ideally these two calls would be done in AudioInterface::Init so that we don't + // need to have a dependency on AudioInterface here, but this has to be done + // after creating g_sound_stream (above) and before starting audio dumping (below) + g_sound_stream->GetMixer()->SetDMAInputSampleRate(AudioInterface::GetAIDSampleRate()); + g_sound_stream->GetMixer()->SetStreamInputSampleRate(AudioInterface::GetAISSampleRate()); + UpdateSoundStream(); SetSoundStreamRunning(true); diff --git a/Source/Core/Core/HW/AudioInterface.cpp b/Source/Core/Core/HW/AudioInterface.cpp index 0f9afc57c9..84d6a835bb 100644 --- a/Source/Core/Core/HW/AudioInterface.cpp +++ b/Source/Core/Core/HW/AudioInterface.cpp @@ -293,11 +293,16 @@ bool IsPlaying() return (s_control.PSTAT == 1); } -unsigned int GetAIDSampleRate() +u32 GetAIDSampleRate() { return s_aid_sample_rate; } +u32 GetAISSampleRate() +{ + return s_ais_sample_rate; +} + u32 Get32KHzSampleRate() { return SConfig::GetInstance().bWii ? 32000 : 32029; diff --git a/Source/Core/Core/HW/AudioInterface.h b/Source/Core/Core/HW/AudioInterface.h index 2ffbaeadf7..92d15b1f2b 100644 --- a/Source/Core/Core/HW/AudioInterface.h +++ b/Source/Core/Core/HW/AudioInterface.h @@ -24,7 +24,8 @@ bool IsPlaying(); void RegisterMMIO(MMIO::Mapping* mmio, u32 base); // Get the audio rates (48000 or 32000 only) -unsigned int GetAIDSampleRate(); +u32 GetAIDSampleRate(); +u32 GetAISSampleRate(); u32 Get32KHzSampleRate(); u32 Get48KHzSampleRate(); diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index 5dddd88f3d..89de61ab06 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -294,7 +294,8 @@ static u32 AdvanceDTK(u32 maximum_samples, u32* samples_to_process) static void DTKStreamingCallback(DIInterruptType interrupt_type, const std::vector& audio_data, s64 cycles_late) { - // TODO: Should we use the configured AIS sample rate instead of a fixed 48 KHz? + // TODO: Should we use GetAISSampleRate instead of a fixed 48 KHz? The audio mixer is using + // GetAISSampleRate. (This doesn't affect any actual games, since they all set it to 48 KHz.) const u32 sample_rate = AudioInterface::Get48KHzSampleRate(); // Determine which audio data to read next.