From 0490c6753fb4c56fc4b9835b504618e6d8101f18 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 1 May 2024 01:56:17 +0300 Subject: [PATCH 1/4] HLE DSP: Stub AAC --- CMakeLists.txt | 2 +- include/audio/aac.hpp | 71 +++++++++++++++++++++++++++++++++++++ include/audio/hle_core.hpp | 2 ++ src/core/audio/hle_core.cpp | 47 ++++++++++++++++++++++-- 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 include/audio/aac.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d3901b6..48a2a0db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,7 +241,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp include/PICA/dynapica/shader_rec_emitter_arm64.hpp include/scheduler.hpp include/applets/error_applet.hpp include/audio/dsp_core.hpp include/audio/null_core.hpp include/audio/teakra_core.hpp include/audio/miniaudio_device.hpp include/ring_buffer.hpp include/bitfield.hpp include/audio/dsp_shared_mem.hpp - include/audio/hle_core.hpp include/capstone.hpp + include/audio/hle_core.hpp include/capstone.hpp include/audio/aac.hpp ) cmrc_add_resource_library( diff --git a/include/audio/aac.hpp b/include/audio/aac.hpp new file mode 100644 index 00000000..c780e6d2 --- /dev/null +++ b/include/audio/aac.hpp @@ -0,0 +1,71 @@ +#pragma once +#include +#include + +#include "helpers.hpp" +#include "swap.hpp" + +namespace Audio::AAC { + namespace ResultCode { + enum : u32 { + Success = 0, + }; + } + + // Enum values from Citra and struct definitions based off Citra + namespace Command { + enum : u16 { + Init = 0, // Initialize encoder/decoder + EncodeDecode = 1, // Encode/Decode AAC + Shutdown = 2, // Shutdown encoder/decoder + LoadState = 3, + SaveState = 4, + }; + } + + namespace SampleRate { + enum : u32 { + Rate48000 = 0, + Rate44100 = 1, + Rate32000 = 2, + Rate24000 = 3, + Rate22050 = 4, + Rate16000 = 5, + Rate12000 = 6, + Rate11025 = 7, + Rate8000 = 8, + }; + } + + namespace Mode { + enum : u16 { + None = 0, + Decode = 1, + Encode = 2, + }; + } + + struct DecodeResponse { + u32_le sampleRate = SampleRate::Rate48000; + u32_le channelCount = 0; + u32_le size = 0; + u32_le unknown1 = 0; + u32_le unknown2 = 0; + u32_le sampleCount = 0; + }; + + struct Message { + u16_le mode = Mode::None; // Encode or decode AAC? + u16_le command = Command::Init; + u32_le resultCode = ResultCode::Success; + + // Info on the AAC request + union { + std::array commandData = {}; + DecodeResponse decodeResponse; + }; + }; + + static_assert(sizeof(Message) == 32); + static_assert(std::is_trivially_copyable()); +} // namespace Audio::AAC \ No newline at end of file diff --git a/include/audio/hle_core.hpp b/include/audio/hle_core.hpp index cee2b0c8..c57f221e 100644 --- a/include/audio/hle_core.hpp +++ b/include/audio/hle_core.hpp @@ -5,6 +5,7 @@ #include #include +#include "audio/aac.hpp" #include "audio/dsp_core.hpp" #include "audio/dsp_shared_mem.hpp" #include "memory.hpp" @@ -166,6 +167,7 @@ namespace Audio { } } + void handleAACRequest(const AAC::Message& request); void updateSourceConfig(Source& source, HLE::SourceConfiguration::Configuration& config, s16_le* adpcmCoefficients); void generateFrame(StereoFrame& frame); void generateFrame(DSPSource& source); diff --git a/src/core/audio/hle_core.cpp b/src/core/audio/hle_core.cpp index d6ba21ec..98d07ce6 100644 --- a/src/core/audio/hle_core.cpp +++ b/src/core/audio/hle_core.cpp @@ -149,12 +149,24 @@ namespace Audio { break; } - case DSPPipeType::Binary: - Helpers::warn("Unimplemented write to binary pipe! Size: %d\n", size); + case DSPPipeType::Binary: { + log("Unimplemented write to binary pipe! Size: %d\n", size); + + AAC::Message request; + if (size == sizeof(request)) { + std::array raw; + for (uint i = 0; i < size; i++) { + raw[i] = mem.read32(buffer + i); + } + + std::memcpy(&request, raw.data(), sizeof(request)); + handleAACRequest(request); + } // This pipe and interrupt are normally used for requests like AAC decode dspService.triggerPipeEvent(DSPPipeType::Binary); break; + } default: log("Audio::HLE_DSP: Wrote to unimplemented pipe %d\n", channel); break; } @@ -488,6 +500,37 @@ namespace Audio { return decodedSamples; } + void HLE_DSP::handleAACRequest(const AAC::Message& request) { + AAC::Message response = {}; + + switch (request.command) { + case AAC::Command::EncodeDecode: + // Dummy response to stop games from hanging + // TODO: Fix this when implementing AAC + response.resultCode = AAC::ResultCode::Success; + response.decodeResponse.channelCount = 2; + response.decodeResponse.sampleCount = 1024; + response.decodeResponse.size = 0; + response.decodeResponse.sampleRate = AAC::SampleRate::Rate48000; + break; + + case AAC::Command::Init: + case AAC::Command::Shutdown: + case AAC::Command::LoadState: + case AAC::Command::SaveState: + response = request; + response.resultCode = AAC::ResultCode::Success; + break; + + default: Helpers::warn("Unknown AAC command type"); break; + } + + // Copy response data to the binary pipe + auto& pipe = pipeData[DSPPipeType::Binary]; + pipe.resize(sizeof(response)); + std::memcpy(&pipe[0], &response, sizeof(response)); + } + void DSPSource::reset() { enabled = false; isBufferIDDirty = false; From ad380b8c5ae9bb8e9a2ce5bdd470a31f04385f20 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 1 May 2024 01:59:32 +0300 Subject: [PATCH 2/4] Warn on invalid AAC request --- src/core/audio/hle_core.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/audio/hle_core.cpp b/src/core/audio/hle_core.cpp index 98d07ce6..e38d4821 100644 --- a/src/core/audio/hle_core.cpp +++ b/src/core/audio/hle_core.cpp @@ -161,6 +161,8 @@ namespace Audio { std::memcpy(&request, raw.data(), sizeof(request)); handleAACRequest(request); + } else { + Helpers::warn("Invalid size for AAC request"); } // This pipe and interrupt are normally used for requests like AAC decode From e4b81d61a46816116808d868eb3d39b96313acb4 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 1 May 2024 16:10:51 +0300 Subject: [PATCH 3/4] HLE DSP: Fix AAC response stub --- include/audio/dsp_shared_mem.hpp | 4 ++-- src/core/audio/hle_core.cpp | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/audio/dsp_shared_mem.hpp b/include/audio/dsp_shared_mem.hpp index 25806ea1..e776211d 100644 --- a/include/audio/dsp_shared_mem.hpp +++ b/include/audio/dsp_shared_mem.hpp @@ -294,12 +294,12 @@ namespace Audio::HLE { struct SourceStatus { struct Status { - u8 isEnabled; ///< Is this channel enabled? (Doesn't have to be playing anything.) + u8 enabled; ///< Is this channel enabled? (Doesn't have to be playing anything.) u8 currentBufferIDDirty; ///< Non-zero when current_buffer_id changes u16_le syncCount; ///< Is set by the DSP to the value of SourceConfiguration::sync_count u32_dsp samplePosition; ///< Number of samples into the current buffer u16_le currentBufferID; ///< Updated when a buffer finishes playing - u16_le lastBufferID; ///< Updated when all buffers in the queue finish playing + u16_le previousBufferID; ///< Updated when all buffers in the queue finish playing }; Status status[sourceCount]; diff --git a/src/core/audio/hle_core.cpp b/src/core/audio/hle_core.cpp index e38d4821..146c7bdf 100644 --- a/src/core/audio/hle_core.cpp +++ b/src/core/audio/hle_core.cpp @@ -229,11 +229,11 @@ namespace Audio { // Update write region of shared memory auto& status = write.sourceStatuses.status[i]; - status.isEnabled = source.enabled; + status.enabled = source.enabled; status.syncCount = source.syncCount; status.currentBufferIDDirty = source.isBufferIDDirty ? 1 : 0; status.currentBufferID = source.currentBufferID; - status.lastBufferID = source.previousBufferID; + status.previousBufferID = source.previousBufferID; // TODO: Properly update sample position status.samplePosition = source.samplePosition; @@ -503,7 +503,7 @@ namespace Audio { } void HLE_DSP::handleAACRequest(const AAC::Message& request) { - AAC::Message response = {}; + AAC::Message response; switch (request.command) { case AAC::Command::EncodeDecode: @@ -514,6 +514,9 @@ namespace Audio { response.decodeResponse.sampleCount = 1024; response.decodeResponse.size = 0; response.decodeResponse.sampleRate = AAC::SampleRate::Rate48000; + + response.command = request.command; + response.mode = request.mode; break; case AAC::Command::Init: From 6a424a7a66bac534800746cd90b2d7d26786bf86 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 1 May 2024 16:20:24 +0300 Subject: [PATCH 4/4] Fix CI --- include/audio/aac.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/audio/aac.hpp b/include/audio/aac.hpp index c780e6d2..afd2dbba 100644 --- a/include/audio/aac.hpp +++ b/include/audio/aac.hpp @@ -12,7 +12,7 @@ namespace Audio::AAC { }; } - // Enum values from Citra and struct definitions based off Citra + // Enum values and struct definitions based off Citra namespace Command { enum : u16 { Init = 0, // Initialize encoder/decoder @@ -46,12 +46,12 @@ namespace Audio::AAC { } struct DecodeResponse { - u32_le sampleRate = SampleRate::Rate48000; - u32_le channelCount = 0; - u32_le size = 0; - u32_le unknown1 = 0; - u32_le unknown2 = 0; - u32_le sampleCount = 0; + u32_le sampleRate; + u32_le channelCount; + u32_le size; + u32_le unknown1; + u32_le unknown2; + u32_le sampleCount; }; struct Message { @@ -61,11 +61,11 @@ namespace Audio::AAC { // Info on the AAC request union { - std::array commandData = {}; + std::array commandData{}; DecodeResponse decodeResponse; }; }; static_assert(sizeof(Message) == 32); static_assert(std::is_trivially_copyable()); -} // namespace Audio::AAC \ No newline at end of file +} // namespace Audio::AAC