diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/audio_core.cpp | 19 | ||||
| -rw-r--r-- | src/audio_core/audio_core.h | 13 | ||||
| -rw-r--r-- | src/audio_core/hle/dsp.cpp | 14 | ||||
| -rw-r--r-- | src/audio_core/hle/dsp.h | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory.cpp | 7 |
5 files changed, 42 insertions, 32 deletions
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 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | ||
| 5 | #include <memory> | 6 | #include <memory> |
| 6 | #include <string> | 7 | #include <string> |
| 7 | #include "audio_core/audio_core.h" | 8 | #include "audio_core/audio_core.h" |
| @@ -10,8 +11,8 @@ | |||
| 10 | #include "audio_core/null_sink.h" | 11 | #include "audio_core/null_sink.h" |
| 11 | #include "audio_core/sink.h" | 12 | #include "audio_core/sink.h" |
| 12 | #include "audio_core/sink_details.h" | 13 | #include "audio_core/sink_details.h" |
| 14 | #include "common/common_types.h" | ||
| 13 | #include "core/core_timing.h" | 15 | #include "core/core_timing.h" |
| 14 | #include "core/hle/kernel/vm_manager.h" | ||
| 15 | #include "core/hle/service/dsp_dsp.h" | 16 | #include "core/hle/service/dsp_dsp.h" |
| 16 | 17 | ||
| 17 | namespace AudioCore { | 18 | namespace AudioCore { |
| @@ -39,20 +40,8 @@ void Init() { | |||
| 39 | CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event); | 40 | CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event); |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | void AddAddressSpace(Kernel::VMManager& address_space) { | 43 | std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory() { |
| 43 | auto r0_vma = address_space | 44 | return DSP::HLE::g_dsp_memory.raw_memory; |
| 44 | .MapBackingMemory(DSP::HLE::region0_base, | ||
| 45 | reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]), | ||
| 46 | sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO) | ||
| 47 | .MoveFrom(); | ||
| 48 | address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite); | ||
| 49 | |||
| 50 | auto r1_vma = address_space | ||
| 51 | .MapBackingMemory(DSP::HLE::region1_base, | ||
| 52 | reinterpret_cast<u8*>(&DSP::HLE::g_regions[1]), | ||
| 53 | sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO) | ||
| 54 | .MoveFrom(); | ||
| 55 | address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite); | ||
| 56 | } | 45 | } |
| 57 | 46 | ||
| 58 | void SelectSink(std::string sink_id) { | 47 | 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 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <string> | 8 | #include <string> |
| 8 | 9 | #include "common/common_types.h" | |
| 9 | namespace Kernel { | 10 | #include "core/memory.h" |
| 10 | class VMManager; | ||
| 11 | } | ||
| 12 | 11 | ||
| 13 | namespace AudioCore { | 12 | namespace AudioCore { |
| 14 | 13 | ||
| @@ -17,8 +16,8 @@ constexpr int native_sample_rate = 32728; ///< 32kHz | |||
| 17 | /// Initialise Audio Core | 16 | /// Initialise Audio Core |
| 18 | void Init(); | 17 | void Init(); |
| 19 | 18 | ||
| 20 | /// Add DSP address spaces to a Process. | 19 | /// Returns a reference to the array backing DSP memory |
| 21 | void AddAddressSpace(Kernel::VMManager& vm_manager); | 20 | std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory(); |
| 22 | 21 | ||
| 23 | /// Select the sink to use based on sink id. | 22 | /// Select the sink to use based on sink id. |
| 24 | void SelectSink(std::string sink_id); | 23 | void SelectSink(std::string sink_id); |
| @@ -29,4 +28,4 @@ void EnableStretching(bool enable); | |||
| 29 | /// Shutdown Audio Core | 28 | /// Shutdown Audio Core |
| 30 | void Shutdown(); | 29 | void Shutdown(); |
| 31 | 30 | ||
| 32 | } // namespace | 31 | } // 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 { | |||
| 16 | 16 | ||
| 17 | // Region management | 17 | // Region management |
| 18 | 18 | ||
| 19 | std::array<SharedMemory, 2> g_regions; | 19 | DspMemory g_dsp_memory; |
| 20 | 20 | ||
| 21 | static size_t CurrentRegionIndex() { | 21 | static size_t CurrentRegionIndex() { |
| 22 | // The region with the higher frame counter is chosen unless there is wraparound. | 22 | // The region with the higher frame counter is chosen unless there is wraparound. |
| 23 | // This function only returns a 0 or 1. | 23 | // This function only returns a 0 or 1. |
| 24 | u16 frame_counter_0 = g_dsp_memory.region_0.frame_counter; | ||
| 25 | u16 frame_counter_1 = g_dsp_memory.region_1.frame_counter; | ||
| 24 | 26 | ||
| 25 | if (g_regions[0].frame_counter == 0xFFFFu && g_regions[1].frame_counter != 0xFFFEu) { | 27 | if (frame_counter_0 == 0xFFFFu && frame_counter_1 != 0xFFFEu) { |
| 26 | // Wraparound has occurred. | 28 | // Wraparound has occurred. |
| 27 | return 1; | 29 | return 1; |
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | if (g_regions[1].frame_counter == 0xFFFFu && g_regions[0].frame_counter != 0xFFFEu) { | 32 | if (frame_counter_1 == 0xFFFFu && frame_counter_0 != 0xFFFEu) { |
| 31 | // Wraparound has occurred. | 33 | // Wraparound has occurred. |
| 32 | return 0; | 34 | return 0; |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | return (g_regions[0].frame_counter > g_regions[1].frame_counter) ? 0 : 1; | 37 | return (frame_counter_0 > frame_counter_1) ? 0 : 1; |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | static SharedMemory& ReadRegion() { | 40 | static SharedMemory& ReadRegion() { |
| 39 | return g_regions[CurrentRegionIndex()]; | 41 | return CurrentRegionIndex() == 0 ? g_dsp_memory.region_0 : g_dsp_memory.region_1; |
| 40 | } | 42 | } |
| 41 | 43 | ||
| 42 | static SharedMemory& WriteRegion() { | 44 | static SharedMemory& WriteRegion() { |
| 43 | return g_regions[1 - CurrentRegionIndex()]; | 45 | return CurrentRegionIndex() != 0 ? g_dsp_memory.region_0 : g_dsp_memory.region_1; |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | // Audio processing and mixing | 48 | // 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 { | |||
| 31 | // double-buffer. The frame counter is located as the very last u16 of each region and is | 31 | // double-buffer. The frame counter is located as the very last u16 of each region and is |
| 32 | // incremented each audio tick. | 32 | // incremented each audio tick. |
| 33 | 33 | ||
| 34 | constexpr VAddr region0_base = 0x1FF50000; | 34 | constexpr u32 region0_offset = 0x50000; |
| 35 | constexpr VAddr region1_base = 0x1FF70000; | 35 | constexpr u32 region1_offset = 0x70000; |
| 36 | 36 | ||
| 37 | /** | 37 | /** |
| 38 | * The DSP is native 16-bit. The DSP also appears to be big-endian. When reading 32-bit numbers from | 38 | * 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 { | |||
| 512 | }; | 512 | }; |
| 513 | ASSERT_DSP_STRUCT(SharedMemory, 0x8000); | 513 | ASSERT_DSP_STRUCT(SharedMemory, 0x8000); |
| 514 | 514 | ||
| 515 | extern std::array<SharedMemory, 2> g_regions; | 515 | union DspMemory { |
| 516 | std::array<u8, 0x80000> raw_memory; | ||
| 517 | struct { | ||
| 518 | u8 unused_0[0x50000]; | ||
| 519 | SharedMemory region_0; | ||
| 520 | u8 unused_1[0x18000]; | ||
| 521 | SharedMemory region_1; | ||
| 522 | u8 unused_2[0x8000]; | ||
| 523 | }; | ||
| 524 | }; | ||
| 525 | static_assert(offsetof(DspMemory, region_0) == region0_offset, | ||
| 526 | "DSP region 0 is at the wrong offset"); | ||
| 527 | static_assert(offsetof(DspMemory, region_1) == region1_offset, | ||
| 528 | "DSP region 1 is at the wrong offset"); | ||
| 529 | |||
| 530 | extern DspMemory g_dsp_memory; | ||
| 516 | 531 | ||
| 517 | // Structures must have an offset that is a multiple of two. | 532 | // Structures must have an offset that is a multiple of two. |
| 518 | static_assert(offsetof(SharedMemory, frame_counter) % 2 == 0, | 533 | 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) { | |||
| 137 | .MoveFrom(); | 137 | .MoveFrom(); |
| 138 | address_space.Reprotect(shared_page_vma, VMAPermission::Read); | 138 | address_space.Reprotect(shared_page_vma, VMAPermission::Read); |
| 139 | 139 | ||
| 140 | AudioCore::AddAddressSpace(address_space); | 140 | auto& dsp_ram = AudioCore::GetDspMemory(); |
| 141 | auto dsp_vma = address_space | ||
| 142 | .MapBackingMemory(DSP_RAM_VADDR, dsp_ram.data(), dsp_ram.size(), | ||
| 143 | Kernel::MemoryState::IO) | ||
| 144 | .MoveFrom(); | ||
| 145 | address_space.Reprotect(dsp_vma, Kernel::VMAPermission::ReadWrite); | ||
| 141 | } | 146 | } |
| 142 | 147 | ||
| 143 | } // namespace | 148 | } // namespace |