diff --git a/Source/Core/AudioCommon/AudioCommon.cpp b/Source/Core/AudioCommon/AudioCommon.cpp index 19ac9f6e9f..8800fddcf5 100644 --- a/Source/Core/AudioCommon/AudioCommon.cpp +++ b/Source/Core/AudioCommon/AudioCommon.cpp @@ -19,15 +19,10 @@ #include "Common/Logging/Log.h" #include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" - -// This shouldn't be a global, at least not here. -std::unique_ptr g_sound_stream; +#include "Core/System.h" namespace AudioCommon { -static bool s_audio_dump_start = false; -static bool s_sound_stream_running = false; - constexpr int AUDIO_VOLUME_MIN = 0; constexpr int AUDIO_VOLUME_MAX = 100; @@ -53,44 +48,50 @@ static std::unique_ptr CreateSoundStreamForBackend(std::string_view void InitSoundStream() { std::string backend = Config::Get(Config::MAIN_AUDIO_BACKEND); - g_sound_stream = CreateSoundStreamForBackend(backend); + std::unique_ptr sound_stream = CreateSoundStreamForBackend(backend); - if (!g_sound_stream) + if (!sound_stream) { WARN_LOG_FMT(AUDIO, "Unknown backend {}, using {} instead.", backend, GetDefaultSoundBackend()); backend = GetDefaultSoundBackend(); - g_sound_stream = CreateSoundStreamForBackend(GetDefaultSoundBackend()); + sound_stream = CreateSoundStreamForBackend(backend); } - if (!g_sound_stream || !g_sound_stream->Init()) + if (!sound_stream || !sound_stream->Init()) { WARN_LOG_FMT(AUDIO, "Could not initialize backend {}, using {} instead.", backend, BACKEND_NULLSOUND); - g_sound_stream = std::make_unique(); - g_sound_stream->Init(); + sound_stream = std::make_unique(); + sound_stream->Init(); } + + Core::System::GetInstance().SetSoundStream(std::move(sound_stream)); } void PostInitSoundStream() { + auto& system = Core::System::GetInstance(); + // This needs to be called after AudioInterface::Init and SerialInterface::Init (for GBA devices) // where input sample rates are set UpdateSoundStream(); SetSoundStreamRunning(true); - if (Config::Get(Config::MAIN_DUMP_AUDIO) && !s_audio_dump_start) + if (Config::Get(Config::MAIN_DUMP_AUDIO) && !system.IsAudioDumpStarted()) StartAudioDump(); } void ShutdownSoundStream() { + auto& system = Core::System::GetInstance(); + INFO_LOG_FMT(AUDIO, "Shutting down sound stream"); - if (Config::Get(Config::MAIN_DUMP_AUDIO) && s_audio_dump_start) + if (Config::Get(Config::MAIN_DUMP_AUDIO) && system.IsAudioDumpStarted()) StopAudioDump(); SetSoundStreamRunning(false); - g_sound_stream.reset(); + system.SetSoundStream(nullptr); INFO_LOG_FMT(AUDIO, "Done shutting down sound stream"); } @@ -162,23 +163,29 @@ bool SupportsVolumeChanges(std::string_view backend) void UpdateSoundStream() { - if (g_sound_stream) + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + + if (sound_stream) { int volume = Config::Get(Config::MAIN_AUDIO_MUTED) ? 0 : Config::Get(Config::MAIN_AUDIO_VOLUME); - g_sound_stream->SetVolume(volume); + sound_stream->SetVolume(volume); } } void SetSoundStreamRunning(bool running) { - if (!g_sound_stream) + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + + if (!sound_stream) return; - if (s_sound_stream_running == running) + if (system.IsSoundStreamRunning() == running) return; - s_sound_stream_running = running; + system.SetSoundStreamRunning(running); - if (g_sound_stream->SetRunning(running)) + if (sound_stream->SetRunning(running)) return; if (running) ERROR_LOG_FMT(AUDIO, "Error starting stream."); @@ -188,24 +195,30 @@ void SetSoundStreamRunning(bool running) void SendAIBuffer(const short* samples, unsigned int num_samples) { - if (!g_sound_stream) + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + + if (!sound_stream) return; - if (Config::Get(Config::MAIN_DUMP_AUDIO) && !s_audio_dump_start) + if (Config::Get(Config::MAIN_DUMP_AUDIO) && !system.IsAudioDumpStarted()) StartAudioDump(); - else if (!Config::Get(Config::MAIN_DUMP_AUDIO) && s_audio_dump_start) + else if (!Config::Get(Config::MAIN_DUMP_AUDIO) && system.IsAudioDumpStarted()) StopAudioDump(); - Mixer* pMixer = g_sound_stream->GetMixer(); + Mixer* mixer = sound_stream->GetMixer(); - if (pMixer && samples) + if (mixer && samples) { - pMixer->PushSamples(samples, num_samples); + mixer->PushSamples(samples, num_samples); } } void StartAudioDump() { + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + std::time_t start_time = std::time(nullptr); std::string path_prefix = File::GetUserPath(D_DUMPAUDIO_IDX) + SConfig::GetInstance().GetGameID(); @@ -217,18 +230,21 @@ void StartAudioDump() const std::string audio_file_name_dsp = fmt::format("{}_dspdump.wav", base_name); File::CreateFullPath(audio_file_name_dtk); File::CreateFullPath(audio_file_name_dsp); - g_sound_stream->GetMixer()->StartLogDTKAudio(audio_file_name_dtk); - g_sound_stream->GetMixer()->StartLogDSPAudio(audio_file_name_dsp); - s_audio_dump_start = true; + sound_stream->GetMixer()->StartLogDTKAudio(audio_file_name_dtk); + sound_stream->GetMixer()->StartLogDSPAudio(audio_file_name_dsp); + system.SetAudioDumpStarted(true); } void StopAudioDump() { - if (!g_sound_stream) + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + + if (!sound_stream) return; - g_sound_stream->GetMixer()->StopLogDTKAudio(); - g_sound_stream->GetMixer()->StopLogDSPAudio(); - s_audio_dump_start = false; + sound_stream->GetMixer()->StopLogDTKAudio(); + sound_stream->GetMixer()->StopLogDSPAudio(); + system.SetAudioDumpStarted(false); } void IncreaseVolume(unsigned short offset) diff --git a/Source/Core/AudioCommon/AudioCommon.h b/Source/Core/AudioCommon/AudioCommon.h index ad0ea820c3..84e3cd0a62 100644 --- a/Source/Core/AudioCommon/AudioCommon.h +++ b/Source/Core/AudioCommon/AudioCommon.h @@ -13,8 +13,6 @@ class Mixer; -extern std::unique_ptr g_sound_stream; - namespace AudioCommon { void InitSoundStream(); diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 26fe5444ba..a3d2379db7 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -956,10 +956,12 @@ void UpdateTitle(u64 elapsed_ms) } // Update the audio timestretcher with the current speed - if (g_sound_stream) + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + if (sound_stream) { - Mixer* pMixer = g_sound_stream->GetMixer(); - pMixer->UpdateSpeed((float)Speed / 100); + Mixer* mixer = sound_stream->GetMixer(); + mixer->UpdateSpeed((float)Speed / 100); } Host_UpdateTitle(message); diff --git a/Source/Core/Core/HW/AudioInterface.cpp b/Source/Core/Core/HW/AudioInterface.cpp index de7590390e..c3b0624289 100644 --- a/Source/Core/Core/HW/AudioInterface.cpp +++ b/Source/Core/Core/HW/AudioInterface.cpp @@ -48,6 +48,7 @@ This file mainly deals with the [Drive I/F], however [AIDFR] controls #include "Core/HW/ProcessorInterface.h" #include "Core/HW/SystemTimers.h" #include "Core/PowerPC/PowerPC.h" +#include "Core/System.h" namespace AudioInterface { @@ -126,7 +127,9 @@ void DoState(PointerWrap& p) p.Do(s_aid_sample_rate_divisor); p.Do(s_cpu_cycles_per_sample); - g_sound_stream->GetMixer()->DoState(p); + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + sound_stream->GetMixer()->DoState(p); } static void GenerateAudioInterrupt(); @@ -155,8 +158,10 @@ void Init() event_type_ai = CoreTiming::RegisterEvent("AICallback", Update); - g_sound_stream->GetMixer()->SetDMAInputSampleRateDivisor(GetAIDSampleRateDivisor()); - g_sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(GetAISSampleRateDivisor()); + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + sound_stream->GetMixer()->SetDMAInputSampleRateDivisor(GetAIDSampleRateDivisor()); + sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(GetAISSampleRateDivisor()); } void Shutdown() @@ -182,6 +187,9 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) s_control.AIINTVLD = tmp_ai_ctrl.AIINTVLD; } + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + // Set frequency of streaming audio if (tmp_ai_ctrl.AISFR != s_control.AISFR) { @@ -191,7 +199,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) s_control.AISFR = tmp_ai_ctrl.AISFR; s_ais_sample_rate_divisor = tmp_ai_ctrl.AISFR ? Get48KHzSampleRateDivisor() : Get32KHzSampleRateDivisor(); - g_sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(s_ais_sample_rate_divisor); + sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(s_ais_sample_rate_divisor); s_cpu_cycles_per_sample = static_cast(SystemTimers::GetTicksPerSecond()) * s_ais_sample_rate_divisor / Mixer::FIXED_SAMPLE_RATE_DIVIDEND; } @@ -203,7 +211,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) s_control.AIDFR = tmp_ai_ctrl.AIDFR; s_aid_sample_rate_divisor = tmp_ai_ctrl.AIDFR ? Get32KHzSampleRateDivisor() : Get48KHzSampleRateDivisor(); - g_sound_stream->GetMixer()->SetDMAInputSampleRateDivisor(s_aid_sample_rate_divisor); + sound_stream->GetMixer()->SetDMAInputSampleRateDivisor(s_aid_sample_rate_divisor); } // Streaming counter @@ -240,7 +248,9 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) mmio->Register(base | AI_VOLUME_REGISTER, MMIO::DirectRead(&s_volume.hex), MMIO::ComplexWrite([](u32, u32 val) { s_volume.hex = val; - g_sound_stream->GetMixer()->SetStreamingVolume(s_volume.left, s_volume.right); + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + sound_stream->GetMixer()->SetStreamingVolume(s_volume.left, s_volume.right); })); mmio->Register(base | AI_SAMPLE_COUNTER, MMIO::ComplexRead([](u32) { diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index bac1652fa0..9cb907a9d5 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -34,6 +34,7 @@ #include "Core/IOS/DI/DI.h" #include "Core/IOS/IOS.h" #include "Core/Movie.h" +#include "Core/System.h" #include "DiscIO/Blob.h" #include "DiscIO/DiscUtils.h" @@ -312,7 +313,10 @@ static void DTKStreamingCallback(DIInterruptType interrupt_type, const std::vect // Send audio to the mixer. std::vector temp_pcm(s_pending_samples * 2, 0); ProcessDTKSamples(&temp_pcm, audio_data); - g_sound_stream->GetMixer()->PushStreamingSamples(temp_pcm.data(), s_pending_samples); + + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + sound_stream->GetMixer()->PushStreamingSamples(temp_pcm.data(), s_pending_samples); if (s_stream && AudioInterface::IsPlaying()) { diff --git a/Source/Core/Core/HW/GBACore.cpp b/Source/Core/Core/HW/GBACore.cpp index d60e1308ad..cb62141522 100644 --- a/Source/Core/Core/HW/GBACore.cpp +++ b/Source/Core/Core/HW/GBACore.cpp @@ -30,6 +30,7 @@ #include "Core/HW/SystemTimers.h" #include "Core/Host.h" #include "Core/NetPlayProto.h" +#include "Core/System.h" namespace HW::GBA { @@ -403,7 +404,10 @@ void Core::SetSampleRates() m_core->setAudioBufferSize(m_core, SAMPLES); blip_set_rates(m_core->getAudioChannel(m_core, 0), m_core->frequency(m_core), SAMPLE_RATE); blip_set_rates(m_core->getAudioChannel(m_core, 1), m_core->frequency(m_core), SAMPLE_RATE); - g_sound_stream->GetMixer()->SetGBAInputSampleRateDivisors( + + auto& system = ::Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + sound_stream->GetMixer()->SetGBAInputSampleRateDivisors( m_device_number, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / SAMPLE_RATE); } @@ -436,7 +440,10 @@ void Core::SetAVStream() std::vector buffer(SAMPLES * 2); blip_read_samples(left, &buffer[0], SAMPLES, 1); blip_read_samples(right, &buffer[1], SAMPLES, 1); - g_sound_stream->GetMixer()->PushGBASamples(core->m_device_number, &buffer[0], SAMPLES); + + auto& system = ::Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + sound_stream->GetMixer()->PushGBASamples(core->m_device_number, &buffer[0], SAMPLES); }; m_core->setAVStream(m_core, &m_stream); } diff --git a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp index 0862fcba76..58295c796d 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp @@ -11,6 +11,7 @@ #include "Common/MathUtil.h" #include "Core/ConfigManager.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" +#include "Core/System.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" @@ -141,11 +142,14 @@ void SpeakerLogic::SpeakerData(const u8* data, int length, float speaker_pan) const u32 l_volume = std::min(u32(std::min(1.f - speaker_pan, 1.f) * volume), 255u); const u32 r_volume = std::min(u32(std::min(1.f + speaker_pan, 1.f) * volume), 255u); - g_sound_stream->GetMixer()->SetWiimoteSpeakerVolume(l_volume, r_volume); + auto& system = Core::System::GetInstance(); + SoundStream* sound_stream = system.GetSoundStream(); + + sound_stream->GetMixer()->SetWiimoteSpeakerVolume(l_volume, r_volume); // ADPCM sample rate is thought to be x2.(3000 x2 = 6000). const unsigned int sample_rate = sample_rate_dividend / reg_data.sample_rate; - g_sound_stream->GetMixer()->PushWiimoteSpeakerSamples( + sound_stream->GetMixer()->PushWiimoteSpeakerSamples( samples.get(), sample_length, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / (sample_rate * 2)); #ifdef WIIMOTE_SPEAKER_DUMP diff --git a/Source/Core/Core/System.cpp b/Source/Core/Core/System.cpp index e7e14ea91e..4320bded39 100644 --- a/Source/Core/Core/System.cpp +++ b/Source/Core/Core/System.cpp @@ -3,12 +3,18 @@ #include "Core/System.h" +#include + +#include "AudioCommon/SoundStream.h" #include "Core/Config/MainSettings.h" namespace Core { struct System::Impl { + std::unique_ptr m_sound_stream; + bool m_sound_stream_running = false; + bool m_audio_dump_started = false; }; System::System() : m_impl{std::make_unique()} @@ -22,4 +28,34 @@ void System::Initialize() m_separate_cpu_and_gpu_threads = Config::Get(Config::MAIN_CPU_THREAD); m_mmu_enabled = Config::Get(Config::MAIN_MMU); } + +SoundStream* System::GetSoundStream() const +{ + return m_impl->m_sound_stream.get(); +} + +void System::SetSoundStream(std::unique_ptr sound_stream) +{ + m_impl->m_sound_stream = std::move(sound_stream); +} + +bool System::IsSoundStreamRunning() const +{ + return m_impl->m_sound_stream_running; +} + +void System::SetSoundStreamRunning(bool running) +{ + m_impl->m_sound_stream_running = running; +} + +bool System::IsAudioDumpStarted() const +{ + return m_impl->m_audio_dump_started; +} + +void System::SetAudioDumpStarted(bool started) +{ + m_impl->m_audio_dump_started = started; +} } // namespace Core diff --git a/Source/Core/Core/System.h b/Source/Core/Core/System.h index 14d48ce477..85b7087095 100644 --- a/Source/Core/Core/System.h +++ b/Source/Core/Core/System.h @@ -5,6 +5,8 @@ #include +class SoundStream; + namespace Core { // Central class that encapsulates the running system. @@ -31,6 +33,13 @@ public: bool IsDualCoreMode() const { return m_separate_cpu_and_gpu_threads; } bool IsMMUMode() const { return m_mmu_enabled; } + SoundStream* GetSoundStream() const; + void SetSoundStream(std::unique_ptr sound_stream); + bool IsSoundStreamRunning() const; + void SetSoundStreamRunning(bool running); + bool IsAudioDumpStarted() const; + void SetAudioDumpStarted(bool started); + private: System(); diff --git a/Source/Core/DolphinQt/GBAWidget.cpp b/Source/Core/DolphinQt/GBAWidget.cpp index 2fd36ac070..f009f4206c 100644 --- a/Source/Core/DolphinQt/GBAWidget.cpp +++ b/Source/Core/DolphinQt/GBAWidget.cpp @@ -26,6 +26,7 @@ #include "Core/HW/SI/SI_Device.h" #include "Core/Movie.h" #include "Core/NetPlayProto.h" +#include "Core/System.h" #include "DolphinQt/QtUtils/DolphinFileDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/Resources.h" @@ -325,7 +326,8 @@ void GBAWidget::UpdateTitle() void GBAWidget::UpdateVolume() { int volume = m_muted ? 0 : m_volume * 256 / 100; - g_sound_stream->GetMixer()->SetGBAVolume(m_core_info.device_number, volume, volume); + auto& system = Core::System::GetInstance(); + system.GetSoundStream()->GetMixer()->SetGBAVolume(m_core_info.device_number, volume, volume); UpdateTitle(); }