From b840c633868109e02d6820ace7d0fc0b158eb003 Mon Sep 17 00:00:00 2001
From: NarcolepticK <NarcolepticKrias@gmail.com>
Date: Tue, 24 Jul 2018 15:54:33 -0400
Subject: [PATCH] service/dsp: Clean up global state

---
 src/audio_core/dsp_interface.h       |  9 +++++++++
 src/audio_core/hle/hle.cpp           | 27 ++++++++++++++++++++++-----
 src/audio_core/hle/hle.h             |  3 +++
 src/core/hle/service/dsp/dsp_dsp.cpp | 18 +++++-------------
 src/core/hle/service/dsp/dsp_dsp.h   |  6 ------
 5 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h
index 4126c03ed..0bf011624 100644
--- a/src/audio_core/dsp_interface.h
+++ b/src/audio_core/dsp_interface.h
@@ -11,6 +11,12 @@
 #include "common/common_types.h"
 #include "core/memory.h"
 
+namespace Service {
+namespace DSP {
+class DSP_DSP;
+} // namespace DSP
+} // namespace Service
+
 namespace AudioCore {
 
 class Sink;
@@ -60,6 +66,9 @@ public:
     /// Returns a reference to the array backing DSP memory
     virtual std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory() = 0;
 
+    /// Sets the dsp class that we trigger interrupts for
+    virtual void SetDspToInterrupt(std::shared_ptr<Service::DSP::DSP_DSP> dsp) = 0;
+
     /// Select the sink to use based on sink id.
     void SetSink(const std::string& sink_id, const std::string& audio_device);
     /// Get the current sink
diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp
index 703112740..e6fee603e 100644
--- a/src/audio_core/hle/hle.cpp
+++ b/src/audio_core/hle/hle.cpp
@@ -13,7 +13,9 @@
 #include "common/common_types.h"
 #include "common/logging/log.h"
 #include "core/core_timing.h"
-#include "core/hle/service/dsp/dsp_dsp.h"
+
+using InterruptType = Service::DSP::DSP_DSP::InterruptType;
+using Service::DSP::DSP_DSP;
 
 namespace AudioCore {
 
@@ -32,6 +34,8 @@ public:
 
     std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory();
 
+    void SetDspToInterrupt(std::shared_ptr<DSP_DSP> dsp);
+
 private:
     void ResetPipes();
     void WriteU16(DspPipe pipe_number, u16 value);
@@ -60,6 +64,8 @@ private:
 
     DspHle& parent;
     CoreTiming::EventType* tick_event;
+
+    std::shared_ptr<DSP_DSP> dsp_dsp;
 };
 
 DspHle::Impl::Impl(DspHle& parent_) : parent(parent_) {
@@ -187,6 +193,10 @@ std::array<u8, Memory::DSP_RAM_SIZE>& DspHle::Impl::GetDspMemory() {
     return dsp_memory.raw_memory;
 }
 
+void DspHle::Impl::SetDspToInterrupt(std::shared_ptr<DSP_DSP> dsp) {
+    dsp_dsp = std::move(dsp);
+}
+
 void DspHle::Impl::ResetPipes() {
     for (auto& data : pipe_data) {
         data.clear();
@@ -231,7 +241,8 @@ void DspHle::Impl::AudioPipeWriteStructAddresses() {
         WriteU16(DspPipe::Audio, addr);
     }
     // Signal that we have data on this pipe.
-    Service::DSP::SignalPipeInterrupt(DspPipe::Audio);
+    if (dsp_dsp)
+        dsp_dsp->SignalInterrupt(InterruptType::Pipe, DspPipe::Audio);
 }
 
 size_t DspHle::Impl::CurrentRegionIndex() const {
@@ -307,9 +318,11 @@ bool DspHle::Impl::Tick() {
 void DspHle::Impl::AudioTickCallback(int cycles_late) {
     if (Tick()) {
         // TODO(merry): Signal all the other interrupts as appropriate.
-        Service::DSP::SignalPipeInterrupt(DspPipe::Audio);
-        // HACK(merry): Added to prevent regressions. Will remove soon.
-        Service::DSP::SignalPipeInterrupt(DspPipe::Binary);
+        if (dsp_dsp) {
+            dsp_dsp->SignalInterrupt(InterruptType::Pipe, DspPipe::Audio);
+            // HACK(merry): Added to prevent regressions. Will remove soon.
+            dsp_dsp->SignalInterrupt(InterruptType::Pipe, DspPipe::Binary);
+        }
     }
 
     // Reschedule recurrent event
@@ -339,4 +352,8 @@ std::array<u8, Memory::DSP_RAM_SIZE>& DspHle::GetDspMemory() {
     return impl->GetDspMemory();
 }
 
+void DspHle::SetDspToInterrupt(std::shared_ptr<DSP_DSP> dsp) {
+    impl->SetDspToInterrupt(std::move(dsp));
+}
+
 } // namespace AudioCore
diff --git a/src/audio_core/hle/hle.h b/src/audio_core/hle/hle.h
index 00ccb6dcf..6189ae989 100644
--- a/src/audio_core/hle/hle.h
+++ b/src/audio_core/hle/hle.h
@@ -10,6 +10,7 @@
 #include "audio_core/audio_types.h"
 #include "audio_core/dsp_interface.h"
 #include "common/common_types.h"
+#include "core/hle/service/dsp/dsp_dsp.h"
 #include "core/memory.h"
 
 namespace AudioCore {
@@ -27,6 +28,8 @@ public:
 
     std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory() override;
 
+    void SetDspToInterrupt(std::shared_ptr<Service::DSP::DSP_DSP> dsp) override;
+
 private:
     struct Impl;
     friend struct Impl;
diff --git a/src/core/hle/service/dsp/dsp_dsp.cpp b/src/core/hle/service/dsp/dsp_dsp.cpp
index 5d1648a15..5d9bb1774 100644
--- a/src/core/hle/service/dsp/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp/dsp_dsp.cpp
@@ -21,8 +21,6 @@ enum class DspPipe;
 namespace Service {
 namespace DSP {
 
-static std::weak_ptr<DSP_DSP> dsp_dsp;
-
 void DSP_DSP::RecvData(Kernel::HLERequestContext& ctx) {
     IPC::RequestParser rp(ctx, 0x01, 1, 0);
     const u32 register_number = rp.Pop<u32>();
@@ -313,6 +311,10 @@ void DSP_DSP::ForceHeadphoneOut(Kernel::HLERequestContext& ctx) {
     LOG_DEBUG(Service_DSP, "(STUBBED) called, force={}", force);
 }
 
+// DSP Interrupts:
+// The audio-pipe interrupt occurs every frame tick. Userland programs normally have a thread
+// that's waiting for an interrupt event. Immediately after this interrupt event, userland
+// normally updates the state in the next region and increments the relevant frame counter by two.
 void DSP_DSP::SignalInterrupt(InterruptType type, DspPipe pipe) {
     LOG_DEBUG(Service_DSP, "called, type={}, pipe={}", static_cast<u32>(type),
               static_cast<u32>(pipe));
@@ -398,20 +400,10 @@ DSP_DSP::~DSP_DSP() {
     pipes = {};
 }
 
-// DSP Interrupts:
-// The audio-pipe interrupt occurs every frame tick. Userland programs normally have a thread
-// that's waiting for an interrupt event. Immediately after this interrupt event, userland
-// normally updates the state in the next region and increments the relevant frame counter by two.
-void SignalPipeInterrupt(DspPipe pipe) {
-    auto dsp = dsp_dsp.lock();
-    ASSERT(dsp != nullptr);
-    return dsp->SignalInterrupt(InterruptType::Pipe, pipe);
-}
-
 void InstallInterfaces(SM::ServiceManager& service_manager) {
     auto dsp = std::make_shared<DSP_DSP>();
     dsp->InstallAsService(service_manager);
-    dsp_dsp = dsp;
+    Core::DSP().SetDspToInterrupt(std::move(dsp));
 }
 
 } // namespace DSP
diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h
index 3b782f9d1..c7213cce4 100644
--- a/src/core/hle/service/dsp/dsp_dsp.h
+++ b/src/core/hle/service/dsp/dsp_dsp.h
@@ -251,12 +251,6 @@ private:
     std::array<Kernel::SharedPtr<Kernel::Event>, AudioCore::num_dsp_pipe> pipes = {{}};
 };
 
-/**
- * Signal a specific DSP related interrupt of type == InterruptType::Pipe, pipe == pipe.
- * @param pipe The DSP pipe for which to signal an interrupt for.
- */
-void SignalPipeInterrupt(AudioCore::DspPipe pipe);
-
 void InstallInterfaces(SM::ServiceManager& service_manager);
 
 } // namespace DSP