mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	audio_core: Clean up AAC decoder infrastructure. (#7310)
This commit is contained in:
		
							parent
							
								
									c6bcbc02de
								
							
						
					
					
						commit
						8e2037b3ff
					
				
					 8 changed files with 63 additions and 146 deletions
				
			
		|  | @ -4,11 +4,11 @@ add_library(audio_core STATIC | ||||||
|     codec.h |     codec.h | ||||||
|     dsp_interface.cpp |     dsp_interface.cpp | ||||||
|     dsp_interface.h |     dsp_interface.h | ||||||
|  |     hle/aac_decoder.cpp | ||||||
|  |     hle/aac_decoder.h | ||||||
|     hle/common.h |     hle/common.h | ||||||
|     hle/decoder.cpp |     hle/decoder.cpp | ||||||
|     hle/decoder.h |     hle/decoder.h | ||||||
|     hle/faad2_decoder.cpp |  | ||||||
|     hle/faad2_decoder.h |  | ||||||
|     hle/filter.cpp |     hle/filter.cpp | ||||||
|     hle/filter.h |     hle/filter.h | ||||||
|     hle/hle.cpp |     hle/hle.cpp | ||||||
|  |  | ||||||
|  | @ -3,30 +3,11 @@ | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include <neaacdec.h> | #include <neaacdec.h> | ||||||
| #include "audio_core/hle/faad2_decoder.h" | #include "audio_core/hle/aac_decoder.h" | ||||||
| 
 | 
 | ||||||
| namespace AudioCore::HLE { | namespace AudioCore::HLE { | ||||||
| 
 | 
 | ||||||
| class FAAD2Decoder::Impl { | AACDecoder::AACDecoder(Memory::MemorySystem& memory) : memory(memory) { | ||||||
| public: |  | ||||||
|     explicit Impl(Memory::MemorySystem& memory); |  | ||||||
|     ~Impl(); |  | ||||||
|     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request); |  | ||||||
|     bool IsValid() const { |  | ||||||
|         return decoder != nullptr; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     std::optional<BinaryMessage> Initalize(const BinaryMessage& request); |  | ||||||
| 
 |  | ||||||
|     std::optional<BinaryMessage> Decode(const BinaryMessage& request); |  | ||||||
| 
 |  | ||||||
|     Memory::MemorySystem& memory; |  | ||||||
| 
 |  | ||||||
|     NeAACDecHandle decoder = nullptr; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| FAAD2Decoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { |  | ||||||
|     decoder = NeAACDecOpen(); |     decoder = NeAACDecOpen(); | ||||||
|     if (decoder == nullptr) { |     if (decoder == nullptr) { | ||||||
|         LOG_CRITICAL(Audio_DSP, "Could not open FAAD2 decoder."); |         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."); |     LOG_INFO(Audio_DSP, "Created FAAD2 AAC decoder."); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FAAD2Decoder::Impl::~Impl() { | AACDecoder::~AACDecoder() { | ||||||
|     if (decoder) { |     if (decoder) { | ||||||
|         NeAACDecClose(decoder); |         NeAACDecClose(decoder); | ||||||
|         decoder = nullptr; |         decoder = nullptr; | ||||||
|  | @ -55,16 +36,23 @@ FAAD2Decoder::Impl::~Impl() { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryMessage> FAAD2Decoder::Impl::ProcessRequest(const BinaryMessage& request) { | BinaryMessage AACDecoder::ProcessRequest(const BinaryMessage& request) { | ||||||
|     if (request.header.codec != DecoderCodec::DecodeAAC) { |     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<u16>(request.header.codec)); |                   static_cast<u16>(request.header.codec)); | ||||||
|         return {}; |         return { | ||||||
|  |             .header = | ||||||
|  |                 { | ||||||
|  |                     .result = ResultStatus::Error, | ||||||
|  |                 }, | ||||||
|  |         }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (request.header.cmd) { |     switch (request.header.cmd) { | ||||||
|     case DecoderCommand::Init: { |     case DecoderCommand::Init: { | ||||||
|         return Initalize(request); |         BinaryMessage response = request; | ||||||
|  |         response.header.result = ResultStatus::Success; | ||||||
|  |         return response; | ||||||
|     } |     } | ||||||
|     case DecoderCommand::EncodeDecode: { |     case DecoderCommand::EncodeDecode: { | ||||||
|         return Decode(request); |         return Decode(request); | ||||||
|  | @ -72,26 +60,25 @@ std::optional<BinaryMessage> FAAD2Decoder::Impl::ProcessRequest(const BinaryMess | ||||||
|     case DecoderCommand::Shutdown: |     case DecoderCommand::Shutdown: | ||||||
|     case DecoderCommand::SaveState: |     case DecoderCommand::SaveState: | ||||||
|     case DecoderCommand::LoadState: { |     case DecoderCommand::LoadState: { | ||||||
|         LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}", |         LOG_WARNING(Audio_DSP, "Got unimplemented AAC binary request: {}", | ||||||
|                     static_cast<u16>(request.header.cmd)); |                     static_cast<u16>(request.header.cmd)); | ||||||
|         BinaryMessage response = request; |         BinaryMessage response = request; | ||||||
|         response.header.result = ResultStatus::Success; |         response.header.result = ResultStatus::Success; | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|     default: |     default: | ||||||
|         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", |         LOG_ERROR(Audio_DSP, "Got unknown AAC binary request: {}", | ||||||
|                   static_cast<u16>(request.header.cmd)); |                   static_cast<u16>(request.header.cmd)); | ||||||
|         return {}; |         return { | ||||||
|  |             .header = | ||||||
|  |                 { | ||||||
|  |                     .result = ResultStatus::Error, | ||||||
|  |                 }, | ||||||
|  |         }; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryMessage> FAAD2Decoder::Impl::Initalize(const BinaryMessage& request) { | BinaryMessage AACDecoder::Decode(const BinaryMessage& request) { | ||||||
|     BinaryMessage response = request; |  | ||||||
|     response.header.result = ResultStatus::Success; |  | ||||||
|     return response; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| std::optional<BinaryMessage> FAAD2Decoder::Impl::Decode(const BinaryMessage& request) { |  | ||||||
|     BinaryMessage response{}; |     BinaryMessage response{}; | ||||||
|     response.header.codec = request.header.codec; |     response.header.codec = request.header.codec; | ||||||
|     response.header.cmd = request.header.cmd; |     response.header.cmd = request.header.cmd; | ||||||
|  | @ -101,6 +88,10 @@ std::optional<BinaryMessage> FAAD2Decoder::Impl::Decode(const BinaryMessage& req | ||||||
|     response.decode_aac_response.num_channels = 2; |     response.decode_aac_response.num_channels = 2; | ||||||
|     response.decode_aac_response.num_samples = 1024; |     response.decode_aac_response.num_samples = 1024; | ||||||
| 
 | 
 | ||||||
|  |     if (decoder == nullptr) { | ||||||
|  |         return response; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || |     if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || | ||||||
|         request.decode_aac_request.src_addr + request.decode_aac_request.size > |         request.decode_aac_request.src_addr + request.decode_aac_request.size > | ||||||
|             Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |             Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  | @ -171,16 +162,4 @@ std::optional<BinaryMessage> FAAD2Decoder::Impl::Decode(const BinaryMessage& req | ||||||
|     return response; |     return response; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FAAD2Decoder::FAAD2Decoder(Memory::MemorySystem& memory) : impl(std::make_unique<Impl>(memory)) {} |  | ||||||
| 
 |  | ||||||
| FAAD2Decoder::~FAAD2Decoder() = default; |  | ||||||
| 
 |  | ||||||
| std::optional<BinaryMessage> FAAD2Decoder::ProcessRequest(const BinaryMessage& request) { |  | ||||||
|     return impl->ProcessRequest(request); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool FAAD2Decoder::IsValid() const { |  | ||||||
|     return impl->IsValid(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| } // namespace AudioCore::HLE
 | } // namespace AudioCore::HLE
 | ||||||
							
								
								
									
										26
									
								
								src/audio_core/hle/aac_decoder.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/audio_core/hle/aac_decoder.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||||
|  | @ -32,34 +32,4 @@ DecoderSampleRate GetSampleRateEnum(u32 sample_rate) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DecoderBase::~DecoderBase(){}; |  | ||||||
| 
 |  | ||||||
| NullDecoder::NullDecoder() = default; |  | ||||||
| 
 |  | ||||||
| NullDecoder::~NullDecoder() = default; |  | ||||||
| 
 |  | ||||||
| std::optional<BinaryMessage> 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<u16>(request.header.cmd)); |  | ||||||
|         return std::nullopt; |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
| } // namespace AudioCore::HLE
 | } // namespace AudioCore::HLE
 | ||||||
|  |  | ||||||
|  | @ -135,21 +135,8 @@ enum_le<DecoderSampleRate> GetSampleRateEnum(u32 sample_rate); | ||||||
| 
 | 
 | ||||||
| class DecoderBase { | class DecoderBase { | ||||||
| public: | public: | ||||||
|     virtual ~DecoderBase(); |     virtual ~DecoderBase() = default; | ||||||
|     virtual std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) = 0; |     virtual BinaryMessage 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<BinaryMessage> ProcessRequest(const BinaryMessage& request) override; |  | ||||||
|     bool IsValid() const override { |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace AudioCore::HLE
 | } // namespace AudioCore::HLE
 | ||||||
|  |  | ||||||
|  | @ -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<BinaryMessage> ProcessRequest(const BinaryMessage& request) override; |  | ||||||
|     bool IsValid() const override; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     class Impl; |  | ||||||
|     std::unique_ptr<Impl> impl; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| } // namespace AudioCore::HLE
 |  | ||||||
|  | @ -8,9 +8,9 @@ | ||||||
| #include <boost/serialization/vector.hpp> | #include <boost/serialization/vector.hpp> | ||||||
| #include <boost/serialization/weak_ptr.hpp> | #include <boost/serialization/weak_ptr.hpp> | ||||||
| #include "audio_core/audio_types.h" | #include "audio_core/audio_types.h" | ||||||
|  | #include "audio_core/hle/aac_decoder.h" | ||||||
| #include "audio_core/hle/common.h" | #include "audio_core/hle/common.h" | ||||||
| #include "audio_core/hle/decoder.h" | #include "audio_core/hle/decoder.h" | ||||||
| #include "audio_core/hle/faad2_decoder.h" |  | ||||||
| #include "audio_core/hle/hle.h" | #include "audio_core/hle/hle.h" | ||||||
| #include "audio_core/hle/mixers.h" | #include "audio_core/hle/mixers.h" | ||||||
| #include "audio_core/hle/shared_memory.h" | #include "audio_core/hle/shared_memory.h" | ||||||
|  | @ -98,7 +98,7 @@ private: | ||||||
|     Core::Timing& core_timing; |     Core::Timing& core_timing; | ||||||
|     Core::TimingEventType* tick_event{}; |     Core::TimingEventType* tick_event{}; | ||||||
| 
 | 
 | ||||||
|     std::unique_ptr<HLE::DecoderBase> decoder{}; |     std::unique_ptr<HLE::DecoderBase> aac_decoder{}; | ||||||
| 
 | 
 | ||||||
|     std::function<void(Service::DSP::InterruptType type, DspPipe pipe)> interrupt_handler{}; |     std::function<void(Service::DSP::InterruptType type, DspPipe pipe)> interrupt_handler{}; | ||||||
| 
 | 
 | ||||||
|  | @ -114,13 +114,6 @@ private: | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static std::vector<std::function<std::unique_ptr<HLE::DecoderBase>(Memory::MemorySystem&)>> |  | ||||||
|     decoder_backends = { |  | ||||||
|         [](Memory::MemorySystem& memory) -> std::unique_ptr<HLE::DecoderBase> { |  | ||||||
|             return std::make_unique<HLE::FAAD2Decoder>(memory); |  | ||||||
|         }, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory, Core::Timing& timing) | DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory, Core::Timing& timing) | ||||||
|     : parent(parent_), core_timing(timing) { |     : parent(parent_), core_timing(timing) { | ||||||
|     dsp_memory.raw_memory.fill(0); |     dsp_memory.raw_memory.fill(0); | ||||||
|  | @ -129,19 +122,7 @@ DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory, Core::Timing& | ||||||
|         source.SetMemory(memory); |         source.SetMemory(memory); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (auto& factory : decoder_backends) { |     aac_decoder = std::make_unique<HLE::AACDecoder>(memory); | ||||||
|         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<HLE::NullDecoder>(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     tick_event = |     tick_event = | ||||||
|         core_timing.RegisterEvent("AudioCore::DspHle::tick_event", [this](u64, s64 cycles_late) { |         core_timing.RegisterEvent("AudioCore::DspHle::tick_event", [this](u64, s64 cycles_late) { | ||||||
|             this->AudioTickCallback(cycles_late); |             this->AudioTickCallback(cycles_late); | ||||||
|  | @ -291,12 +272,9 @@ void DspHle::Impl::PipeWrite(DspPipe pipe_number, std::span<const u8> buffer) { | ||||||
|             UNIMPLEMENTED(); |             UNIMPLEMENTED(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         std::optional<HLE::BinaryMessage> response = decoder->ProcessRequest(request); |         const HLE::BinaryMessage response = aac_decoder->ProcessRequest(request); | ||||||
|         if (response) { |         pipe_data[static_cast<u32>(pipe_number)].resize(sizeof(response)); | ||||||
|             const HLE::BinaryMessage& value = *response; |         std::memcpy(pipe_data[static_cast<u32>(pipe_number)].data(), &response, sizeof(response)); | ||||||
|             pipe_data[static_cast<u32>(pipe_number)].resize(sizeof(value)); |  | ||||||
|             std::memcpy(pipe_data[static_cast<u32>(pipe_number)].data(), &value, sizeof(value)); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         interrupt_handler(InterruptType::Pipe, DspPipe::Binary); |         interrupt_handler(InterruptType::Pipe, DspPipe::Binary); | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue