From 8e2037b3ffced791f1d8f931d15d9e4ab017d7d1 Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:00:03 -0800 Subject: [PATCH] audio_core: Clean up AAC decoder infrastructure. (#7310) --- src/audio_core/CMakeLists.txt | 4 +- .../{faad2_decoder.cpp => aac_decoder.cpp} | 75 +++++++------------ src/audio_core/hle/aac_decoder.h | 26 +++++++ src/audio_core/hle/decoder.cpp | 30 -------- src/audio_core/hle/decoder.h | 17 +---- src/audio_core/hle/faad2_decoder.h | 23 ------ src/audio_core/hle/hle.cpp | 34 ++------- src/audio_core/hle/pipe.h | 0 8 files changed, 63 insertions(+), 146 deletions(-) rename src/audio_core/hle/{faad2_decoder.cpp => aac_decoder.cpp} (74%) create mode 100644 src/audio_core/hle/aac_decoder.h delete mode 100644 src/audio_core/hle/faad2_decoder.h delete mode 100644 src/audio_core/hle/pipe.h diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 2146df6fb3..a000e1fc12 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -4,11 +4,11 @@ add_library(audio_core STATIC codec.h dsp_interface.cpp dsp_interface.h + hle/aac_decoder.cpp + hle/aac_decoder.h hle/common.h hle/decoder.cpp hle/decoder.h - hle/faad2_decoder.cpp - hle/faad2_decoder.h hle/filter.cpp hle/filter.h hle/hle.cpp diff --git a/src/audio_core/hle/faad2_decoder.cpp b/src/audio_core/hle/aac_decoder.cpp similarity index 74% rename from src/audio_core/hle/faad2_decoder.cpp rename to src/audio_core/hle/aac_decoder.cpp index 795c6b0325..7c7bb4f3f6 100644 --- a/src/audio_core/hle/faad2_decoder.cpp +++ b/src/audio_core/hle/aac_decoder.cpp @@ -3,30 +3,11 @@ // Refer to the license.txt file included. #include -#include "audio_core/hle/faad2_decoder.h" +#include "audio_core/hle/aac_decoder.h" namespace AudioCore::HLE { -class FAAD2Decoder::Impl { -public: - explicit Impl(Memory::MemorySystem& memory); - ~Impl(); - std::optional ProcessRequest(const BinaryMessage& request); - bool IsValid() const { - return decoder != nullptr; - } - -private: - std::optional Initalize(const BinaryMessage& request); - - std::optional Decode(const BinaryMessage& request); - - Memory::MemorySystem& memory; - - NeAACDecHandle decoder = nullptr; -}; - -FAAD2Decoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { +AACDecoder::AACDecoder(Memory::MemorySystem& memory) : memory(memory) { decoder = NeAACDecOpen(); if (decoder == nullptr) { LOG_CRITICAL(Audio_DSP, "Could not open FAAD2 decoder."); @@ -46,7 +27,7 @@ FAAD2Decoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { LOG_INFO(Audio_DSP, "Created FAAD2 AAC decoder."); } -FAAD2Decoder::Impl::~Impl() { +AACDecoder::~AACDecoder() { if (decoder) { NeAACDecClose(decoder); decoder = nullptr; @@ -55,16 +36,23 @@ FAAD2Decoder::Impl::~Impl() { } } -std::optional FAAD2Decoder::Impl::ProcessRequest(const BinaryMessage& request) { +BinaryMessage AACDecoder::ProcessRequest(const BinaryMessage& request) { if (request.header.codec != DecoderCodec::DecodeAAC) { - LOG_ERROR(Audio_DSP, "FAAD2 AAC Decoder cannot handle such codec: {}", + LOG_ERROR(Audio_DSP, "AAC decoder received unsupported codec: {}", static_cast(request.header.codec)); - return {}; + return { + .header = + { + .result = ResultStatus::Error, + }, + }; } switch (request.header.cmd) { case DecoderCommand::Init: { - return Initalize(request); + BinaryMessage response = request; + response.header.result = ResultStatus::Success; + return response; } case DecoderCommand::EncodeDecode: { return Decode(request); @@ -72,26 +60,25 @@ std::optional FAAD2Decoder::Impl::ProcessRequest(const BinaryMess case DecoderCommand::Shutdown: case DecoderCommand::SaveState: case DecoderCommand::LoadState: { - LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}", + LOG_WARNING(Audio_DSP, "Got unimplemented AAC binary request: {}", static_cast(request.header.cmd)); BinaryMessage response = request; response.header.result = ResultStatus::Success; return response; } default: - LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", + LOG_ERROR(Audio_DSP, "Got unknown AAC binary request: {}", static_cast(request.header.cmd)); - return {}; + return { + .header = + { + .result = ResultStatus::Error, + }, + }; } } -std::optional FAAD2Decoder::Impl::Initalize(const BinaryMessage& request) { - BinaryMessage response = request; - response.header.result = ResultStatus::Success; - return response; -} - -std::optional FAAD2Decoder::Impl::Decode(const BinaryMessage& request) { +BinaryMessage AACDecoder::Decode(const BinaryMessage& request) { BinaryMessage response{}; response.header.codec = request.header.codec; response.header.cmd = request.header.cmd; @@ -101,6 +88,10 @@ std::optional FAAD2Decoder::Impl::Decode(const BinaryMessage& req response.decode_aac_response.num_channels = 2; response.decode_aac_response.num_samples = 1024; + if (decoder == nullptr) { + return response; + } + if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || request.decode_aac_request.src_addr + request.decode_aac_request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { @@ -171,16 +162,4 @@ std::optional FAAD2Decoder::Impl::Decode(const BinaryMessage& req return response; } -FAAD2Decoder::FAAD2Decoder(Memory::MemorySystem& memory) : impl(std::make_unique(memory)) {} - -FAAD2Decoder::~FAAD2Decoder() = default; - -std::optional FAAD2Decoder::ProcessRequest(const BinaryMessage& request) { - return impl->ProcessRequest(request); -} - -bool FAAD2Decoder::IsValid() const { - return impl->IsValid(); -} - } // namespace AudioCore::HLE diff --git a/src/audio_core/hle/aac_decoder.h b/src/audio_core/hle/aac_decoder.h new file mode 100644 index 0000000000..b3b6a3fea8 --- /dev/null +++ b/src/audio_core/hle/aac_decoder.h @@ -0,0 +1,26 @@ +// Copyright 2023 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "audio_core/hle/decoder.h" + +namespace AudioCore::HLE { + +using NeAACDecHandle = void*; + +class AACDecoder final : public DecoderBase { +public: + explicit AACDecoder(Memory::MemorySystem& memory); + ~AACDecoder() override; + BinaryMessage ProcessRequest(const BinaryMessage& request) override; + +private: + BinaryMessage Decode(const BinaryMessage& request); + + Memory::MemorySystem& memory; + NeAACDecHandle decoder = nullptr; +}; + +} // namespace AudioCore::HLE diff --git a/src/audio_core/hle/decoder.cpp b/src/audio_core/hle/decoder.cpp index 872da9c16c..c05982752b 100644 --- a/src/audio_core/hle/decoder.cpp +++ b/src/audio_core/hle/decoder.cpp @@ -32,34 +32,4 @@ DecoderSampleRate GetSampleRateEnum(u32 sample_rate) { } } -DecoderBase::~DecoderBase(){}; - -NullDecoder::NullDecoder() = default; - -NullDecoder::~NullDecoder() = default; - -std::optional NullDecoder::ProcessRequest(const BinaryMessage& request) { - BinaryMessage response{}; - switch (request.header.cmd) { - case DecoderCommand::Init: - case DecoderCommand::Shutdown: - case DecoderCommand::SaveState: - case DecoderCommand::LoadState: - response = request; - response.header.result = ResultStatus::Success; - return response; - case DecoderCommand::EncodeDecode: - response.header.codec = request.header.codec; - response.header.cmd = request.header.cmd; - response.header.result = ResultStatus::Success; - response.decode_aac_response.num_channels = 2; // Just assume stereo here - response.decode_aac_response.size = request.decode_aac_request.size; - response.decode_aac_response.num_samples = 1024; // Just assume 1024 here - return response; - default: - LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", - static_cast(request.header.cmd)); - return std::nullopt; - } -}; } // namespace AudioCore::HLE diff --git a/src/audio_core/hle/decoder.h b/src/audio_core/hle/decoder.h index d3cc910e8f..53365f45cb 100644 --- a/src/audio_core/hle/decoder.h +++ b/src/audio_core/hle/decoder.h @@ -135,21 +135,8 @@ enum_le GetSampleRateEnum(u32 sample_rate); class DecoderBase { public: - virtual ~DecoderBase(); - virtual std::optional ProcessRequest(const BinaryMessage& request) = 0; - /// Return true if this Decoder can be loaded. Return false if the system cannot create the - /// decoder - virtual bool IsValid() const = 0; -}; - -class NullDecoder final : public DecoderBase { -public: - NullDecoder(); - ~NullDecoder() override; - std::optional ProcessRequest(const BinaryMessage& request) override; - bool IsValid() const override { - return true; - } + virtual ~DecoderBase() = default; + virtual BinaryMessage ProcessRequest(const BinaryMessage& request) = 0; }; } // namespace AudioCore::HLE diff --git a/src/audio_core/hle/faad2_decoder.h b/src/audio_core/hle/faad2_decoder.h deleted file mode 100644 index d67473376f..0000000000 --- a/src/audio_core/hle/faad2_decoder.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2023 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "audio_core/hle/decoder.h" - -namespace AudioCore::HLE { - -class FAAD2Decoder final : public DecoderBase { -public: - explicit FAAD2Decoder(Memory::MemorySystem& memory); - ~FAAD2Decoder() override; - std::optional ProcessRequest(const BinaryMessage& request) override; - bool IsValid() const override; - -private: - class Impl; - std::unique_ptr impl; -}; - -} // namespace AudioCore::HLE diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index af5e82e496..89bb8a5f49 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -8,9 +8,9 @@ #include #include #include "audio_core/audio_types.h" +#include "audio_core/hle/aac_decoder.h" #include "audio_core/hle/common.h" #include "audio_core/hle/decoder.h" -#include "audio_core/hle/faad2_decoder.h" #include "audio_core/hle/hle.h" #include "audio_core/hle/mixers.h" #include "audio_core/hle/shared_memory.h" @@ -98,7 +98,7 @@ private: Core::Timing& core_timing; Core::TimingEventType* tick_event{}; - std::unique_ptr decoder{}; + std::unique_ptr aac_decoder{}; std::function interrupt_handler{}; @@ -114,13 +114,6 @@ private: friend class boost::serialization::access; }; -static std::vector(Memory::MemorySystem&)>> - decoder_backends = { - [](Memory::MemorySystem& memory) -> std::unique_ptr { - return std::make_unique(memory); - }, -}; - DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory, Core::Timing& timing) : parent(parent_), core_timing(timing) { dsp_memory.raw_memory.fill(0); @@ -129,19 +122,7 @@ DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory, Core::Timing& source.SetMemory(memory); } - for (auto& factory : decoder_backends) { - decoder = factory(memory); - if (decoder && decoder->IsValid()) { - break; - } - } - - if (!decoder || !decoder->IsValid()) { - LOG_WARNING(Audio_DSP, - "Unable to load any decoders, this could cause missing audio in some games"); - decoder = std::make_unique(); - } - + aac_decoder = std::make_unique(memory); tick_event = core_timing.RegisterEvent("AudioCore::DspHle::tick_event", [this](u64, s64 cycles_late) { this->AudioTickCallback(cycles_late); @@ -291,12 +272,9 @@ void DspHle::Impl::PipeWrite(DspPipe pipe_number, std::span buffer) { UNIMPLEMENTED(); return; } - std::optional response = decoder->ProcessRequest(request); - if (response) { - const HLE::BinaryMessage& value = *response; - pipe_data[static_cast(pipe_number)].resize(sizeof(value)); - std::memcpy(pipe_data[static_cast(pipe_number)].data(), &value, sizeof(value)); - } + const HLE::BinaryMessage response = aac_decoder->ProcessRequest(request); + pipe_data[static_cast(pipe_number)].resize(sizeof(response)); + std::memcpy(pipe_data[static_cast(pipe_number)].data(), &response, sizeof(response)); interrupt_handler(InterruptType::Pipe, DspPipe::Binary); break; diff --git a/src/audio_core/hle/pipe.h b/src/audio_core/hle/pipe.h deleted file mode 100644 index e69de29bb2..0000000000