diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp
index 84f9c03a7..9c2e6ed88 100644
--- a/src/audio_core/audio_core.cpp
+++ b/src/audio_core/audio_core.cpp
@@ -2,6 +2,7 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include <array>
 #include <memory>
 #include <string>
 #include "audio_core/audio_core.h"
@@ -10,8 +11,8 @@
 #include "audio_core/null_sink.h"
 #include "audio_core/sink.h"
 #include "audio_core/sink_details.h"
+#include "common/common_types.h"
 #include "core/core_timing.h"
-#include "core/hle/kernel/vm_manager.h"
 #include "core/hle/service/dsp_dsp.h"
 
 namespace AudioCore {
@@ -39,20 +40,8 @@ void Init() {
     CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event);
 }
 
-void AddAddressSpace(Kernel::VMManager& address_space) {
-    auto r0_vma = address_space
-                      .MapBackingMemory(DSP::HLE::region0_base,
-                                        reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]),
-                                        sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO)
-                      .MoveFrom();
-    address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite);
-
-    auto r1_vma = address_space
-                      .MapBackingMemory(DSP::HLE::region1_base,
-                                        reinterpret_cast<u8*>(&DSP::HLE::g_regions[1]),
-                                        sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO)
-                      .MoveFrom();
-    address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite);
+std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory() {
+    return DSP::HLE::g_dsp_memory.raw_memory;
 }
 
 void SelectSink(std::string sink_id) {
diff --git a/src/audio_core/audio_core.h b/src/audio_core/audio_core.h
index 0edf6dd15..ab323ce1f 100644
--- a/src/audio_core/audio_core.h
+++ b/src/audio_core/audio_core.h
@@ -4,11 +4,10 @@
 
 #pragma once
 
+#include <array>
 #include <string>
-
-namespace Kernel {
-class VMManager;
-}
+#include "common/common_types.h"
+#include "core/memory.h"
 
 namespace AudioCore {
 
@@ -17,8 +16,8 @@ constexpr int native_sample_rate = 32728; ///< 32kHz
 /// Initialise Audio Core
 void Init();
 
-/// Add DSP address spaces to a Process.
-void AddAddressSpace(Kernel::VMManager& vm_manager);
+/// Returns a reference to the array backing DSP memory
+std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory();
 
 /// Select the sink to use based on sink id.
 void SelectSink(std::string sink_id);
@@ -29,4 +28,4 @@ void EnableStretching(bool enable);
 /// Shutdown Audio Core
 void Shutdown();
 
-} // namespace
+} // namespace AudioCore
diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp
index 31421fdc6..260b182ed 100644
--- a/src/audio_core/hle/dsp.cpp
+++ b/src/audio_core/hle/dsp.cpp
@@ -16,31 +16,33 @@ namespace HLE {
 
 // Region management
 
-std::array<SharedMemory, 2> g_regions;
+DspMemory g_dsp_memory;
 
 static size_t CurrentRegionIndex() {
     // The region with the higher frame counter is chosen unless there is wraparound.
     // This function only returns a 0 or 1.
+    u16 frame_counter_0 = g_dsp_memory.region_0.frame_counter;
+    u16 frame_counter_1 = g_dsp_memory.region_1.frame_counter;
 
-    if (g_regions[0].frame_counter == 0xFFFFu && g_regions[1].frame_counter != 0xFFFEu) {
+    if (frame_counter_0 == 0xFFFFu && frame_counter_1 != 0xFFFEu) {
         // Wraparound has occurred.
         return 1;
     }
 
-    if (g_regions[1].frame_counter == 0xFFFFu && g_regions[0].frame_counter != 0xFFFEu) {
+    if (frame_counter_1 == 0xFFFFu && frame_counter_0 != 0xFFFEu) {
         // Wraparound has occurred.
         return 0;
     }
 
-    return (g_regions[0].frame_counter > g_regions[1].frame_counter) ? 0 : 1;
+    return (frame_counter_0 > frame_counter_1) ? 0 : 1;
 }
 
 static SharedMemory& ReadRegion() {
-    return g_regions[CurrentRegionIndex()];
+    return CurrentRegionIndex() == 0 ? g_dsp_memory.region_0 : g_dsp_memory.region_1;
 }
 
 static SharedMemory& WriteRegion() {
-    return g_regions[1 - CurrentRegionIndex()];
+    return CurrentRegionIndex() != 0 ? g_dsp_memory.region_0 : g_dsp_memory.region_1;
 }
 
 // Audio processing and mixing
diff --git a/src/audio_core/hle/dsp.h b/src/audio_core/hle/dsp.h
index 0a0f60ac1..94ce48863 100644
--- a/src/audio_core/hle/dsp.h
+++ b/src/audio_core/hle/dsp.h
@@ -31,8 +31,8 @@ namespace HLE {
 // double-buffer. The frame counter is located as the very last u16 of each region and is
 // incremented each audio tick.
 
-constexpr VAddr region0_base = 0x1FF50000;
-constexpr VAddr region1_base = 0x1FF70000;
+constexpr u32 region0_offset = 0x50000;
+constexpr u32 region1_offset = 0x70000;
 
 /**
  * The DSP is native 16-bit. The DSP also appears to be big-endian. When reading 32-bit numbers from
@@ -512,7 +512,22 @@ struct SharedMemory {
 };
 ASSERT_DSP_STRUCT(SharedMemory, 0x8000);
 
-extern std::array<SharedMemory, 2> g_regions;
+union DspMemory {
+    std::array<u8, 0x80000> raw_memory;
+    struct {
+        u8 unused_0[0x50000];
+        SharedMemory region_0;
+        u8 unused_1[0x18000];
+        SharedMemory region_1;
+        u8 unused_2[0x8000];
+    };
+};
+static_assert(offsetof(DspMemory, region_0) == region0_offset,
+              "DSP region 0 is at the wrong offset");
+static_assert(offsetof(DspMemory, region_1) == region1_offset,
+              "DSP region 1 is at the wrong offset");
+
+extern DspMemory g_dsp_memory;
 
 // Structures must have an offset that is a multiple of two.
 static_assert(offsetof(SharedMemory, frame_counter) % 2 == 0,
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
index 33c165197..be7c7513f 100644
--- a/src/core/hle/kernel/memory.cpp
+++ b/src/core/hle/kernel/memory.cpp
@@ -137,7 +137,12 @@ void InitLegacyAddressSpace(Kernel::VMManager& address_space) {
                                .MoveFrom();
     address_space.Reprotect(shared_page_vma, VMAPermission::Read);
 
-    AudioCore::AddAddressSpace(address_space);
+    auto& dsp_ram = AudioCore::GetDspMemory();
+    auto dsp_vma = address_space
+                       .MapBackingMemory(DSP_RAM_VADDR, dsp_ram.data(), dsp_ram.size(),
+                                         Kernel::MemoryState::IO)
+                       .MoveFrom();
+    address_space.Reprotect(dsp_vma, Kernel::VMAPermission::ReadWrite);
 }
 
 } // namespace