mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	audio_core/hle: Refactor Binary Pipe data structures
audio_core\hle\ffmpeg_decoder.cpp: renames
This commit is contained in:
		
							parent
							
								
									975ee15635
								
							
						
					
					
						commit
						8cada619b3
					
				
					 15 changed files with 354 additions and 267 deletions
				
			
		|  | @ -17,11 +17,11 @@ class AudioToolboxDecoder::Impl { | ||||||
| public: | public: | ||||||
|     explicit Impl(Memory::MemorySystem& memory); |     explicit Impl(Memory::MemorySystem& memory); | ||||||
|     ~Impl(); |     ~Impl(); | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request); |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     std::optional<BinaryResponse> Initalize(const BinaryRequest& request); |     std::optional<BinaryMessage> Initalize(const BinaryMessage& request); | ||||||
|     std::optional<BinaryResponse> Decode(const BinaryRequest& request); |     std::optional<BinaryMessage> Decode(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     void Clear(); |     void Clear(); | ||||||
|     bool InitializeDecoder(ADTSData& adts_header); |     bool InitializeDecoder(ADTSData& adts_header); | ||||||
|  | @ -43,12 +43,11 @@ private: | ||||||
|     AudioStreamPacketDescription packet_description; |     AudioStreamPacketDescription packet_description; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| AudioToolboxDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) {} | AudioToolboxDecoder::Impl::Impl(Memory::MemorySystem& memory_) : memory(memory_) {} | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> AudioToolboxDecoder::Impl::Initalize(const BinaryRequest& request) { | std::optional<BinaryMessage> AudioToolboxDecoder::Impl::Initalize(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response = request; | ||||||
|     std::memcpy(&response, &request, sizeof(response)); |     response.header.result = ResultStatus::Success; | ||||||
|     response.unknown1 = 0x0; |  | ||||||
| 
 | 
 | ||||||
|     Clear(); |     Clear(); | ||||||
|     return response; |     return response; | ||||||
|  | @ -71,29 +70,29 @@ void AudioToolboxDecoder::Impl::Clear() { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> AudioToolboxDecoder::Impl::ProcessRequest( | std::optional<BinaryMessage> AudioToolboxDecoder::Impl::ProcessRequest( | ||||||
|     const BinaryRequest& request) { |     const BinaryMessage& request) { | ||||||
|     if (request.codec != DecoderCodec::AAC) { |     if (request.header.codec != DecoderCodec::DecodeAAC) { | ||||||
|         LOG_ERROR(Audio_DSP, "AudioToolbox AAC Decoder cannot handle such codec: {}", |         LOG_ERROR(Audio_DSP, "AudioToolbox AAC Decoder cannot handle such codec: {}", | ||||||
|                   static_cast<u16>(request.codec)); |                   static_cast<u16>(request.header.codec)); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (request.cmd) { |     switch (request.header.cmd) { | ||||||
|     case DecoderCommand::Init: { |     case DecoderCommand::Init: { | ||||||
|         return Initalize(request); |         return Initalize(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Decode: { |     case DecoderCommand::EncodeDecode: { | ||||||
|         return Decode(request); |         return Decode(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Unknown: { |     case DecoderCommand::Unknown: { | ||||||
|         BinaryResponse response; |         BinaryMessage response = request; | ||||||
|         std::memcpy(&response, &request, sizeof(response)); |         response.header.result = ResultStatus::Success; | ||||||
|         response.unknown1 = 0x0; |  | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|     default: |     default: | ||||||
|         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast<u16>(request.cmd)); |         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", | ||||||
|  |                   static_cast<u16>(request.header.cmd)); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -166,22 +165,24 @@ OSStatus AudioToolboxDecoder::Impl::DataFunc( | ||||||
|     return noErr; |     return noErr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> AudioToolboxDecoder::Impl::Decode(const BinaryRequest& request) { | std::optional<BinaryMessage> AudioToolboxDecoder::Impl::Decode(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response{}; | ||||||
|     response.codec = request.codec; |     response.header.codec = request.header.codec; | ||||||
|     response.cmd = request.cmd; |     response.header.cmd = request.header.cmd; | ||||||
|     response.size = request.size; |     response.decode_aac_response.size = request.decode_aac_request.size; | ||||||
| 
 | 
 | ||||||
|     if (request.src_addr < Memory::FCRAM_PADDR || |     if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || | ||||||
|         request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |         request.decode_aac_request.src_addr + request.decode_aac_request.size > | ||||||
|         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); |             Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  |         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", | ||||||
|  |                   request.decode_aac_request.src_addr); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto data = memory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); |     auto data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR); | ||||||
|     auto adts_header = ParseADTS(reinterpret_cast<const char*>(data)); |     auto adts_header = ParseADTS(reinterpret_cast<const char*>(data)); | ||||||
|     curr_data = data + adts_header.header_length; |     curr_data = data + adts_header.header_length; | ||||||
|     curr_data_len = request.size - adts_header.header_length; |     curr_data_len = request.decode_aac_request.size - adts_header.header_length; | ||||||
| 
 | 
 | ||||||
|     if (!InitializeDecoder(adts_header)) { |     if (!InitializeDecoder(adts_header)) { | ||||||
|         return std::nullopt; |         return std::nullopt; | ||||||
|  | @ -218,15 +219,17 @@ std::optional<BinaryResponse> AudioToolboxDecoder::Impl::Decode(const BinaryRequ | ||||||
|     curr_data = nullptr; |     curr_data = nullptr; | ||||||
|     curr_data_len = 0; |     curr_data_len = 0; | ||||||
| 
 | 
 | ||||||
|     response.sample_rate = GetSampleRateEnum(static_cast<u32>(output_format.mSampleRate)); |     response.decode_aac_response.sample_rate = | ||||||
|     response.num_channels = output_format.mChannelsPerFrame; |         GetSampleRateEnum(static_cast<u32>(output_format.mSampleRate)); | ||||||
|     response.num_samples = num_frames; |     response.decode_aac_response.num_channels = output_format.mChannelsPerFrame; | ||||||
|  |     response.decode_aac_response.num_samples = num_frames; | ||||||
| 
 | 
 | ||||||
|     // transfer the decoded buffer from vector to the FCRAM
 |     // transfer the decoded buffer from vector to the FCRAM
 | ||||||
|     for (std::size_t ch = 0; ch < out_streams.size(); ch++) { |     for (std::size_t ch = 0; ch < out_streams.size(); ch++) { | ||||||
|         if (!out_streams[ch].empty()) { |         if (!out_streams[ch].empty()) { | ||||||
|             auto byte_size = out_streams[ch].size() * bytes_per_sample; |             auto byte_size = out_streams[ch].size() * bytes_per_sample; | ||||||
|             auto dst = ch == 0 ? request.dst_addr_ch0 : request.dst_addr_ch1; |             auto dst = ch == 0 ? request.decode_aac_request.dst_addr_ch0 | ||||||
|  |                                : request.decode_aac_request.dst_addr_ch1; | ||||||
|             if (dst < Memory::FCRAM_PADDR || |             if (dst < Memory::FCRAM_PADDR || | ||||||
|                 dst + byte_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |                 dst + byte_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|                 LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch{} {:08x}", ch, dst); |                 LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch{} {:08x}", ch, dst); | ||||||
|  | @ -245,7 +248,7 @@ AudioToolboxDecoder::AudioToolboxDecoder(Memory::MemorySystem& memory) | ||||||
| 
 | 
 | ||||||
| AudioToolboxDecoder::~AudioToolboxDecoder() = default; | AudioToolboxDecoder::~AudioToolboxDecoder() = default; | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> AudioToolboxDecoder::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> AudioToolboxDecoder::ProcessRequest(const BinaryMessage& request) { | ||||||
|     return impl->ProcessRequest(request); |     return impl->ProcessRequest(request); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ class AudioToolboxDecoder final : public DecoderBase { | ||||||
| public: | public: | ||||||
|     explicit AudioToolboxDecoder(Memory::MemorySystem& memory); |     explicit AudioToolboxDecoder(Memory::MemorySystem& memory); | ||||||
|     ~AudioToolboxDecoder() override; |     ~AudioToolboxDecoder() override; | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) override; | ||||||
|     bool IsValid() const override; |     bool IsValid() const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |  | ||||||
|  | @ -38,23 +38,25 @@ NullDecoder::NullDecoder() = default; | ||||||
| 
 | 
 | ||||||
| NullDecoder::~NullDecoder() = default; | NullDecoder::~NullDecoder() = default; | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> NullDecoder::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> NullDecoder::ProcessRequest(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response{}; | ||||||
|     switch (request.cmd) { |     switch (request.header.cmd) { | ||||||
|     case DecoderCommand::Init: |     case DecoderCommand::Init: | ||||||
|     case DecoderCommand::Unknown: |     case DecoderCommand::Unknown: | ||||||
|         std::memcpy(&response, &request, sizeof(response)); |         response = request; | ||||||
|         response.unknown1 = 0x0; |         response.header.result = ResultStatus::Success; | ||||||
|         return response; |         return response; | ||||||
|     case DecoderCommand::Decode: |     case DecoderCommand::EncodeDecode: | ||||||
|         response.codec = request.codec; |         response.header.codec = request.header.codec; | ||||||
|         response.cmd = DecoderCommand::Decode; |         response.header.cmd = request.header.cmd; | ||||||
|         response.num_channels = 2; // Just assume stereo here
 |         response.header.result = ResultStatus::Success; | ||||||
|         response.size = request.size; |         response.decode_aac_response.num_channels = 2; // Just assume stereo here
 | ||||||
|         response.num_samples = 1024; // Just assume 1024 here
 |         response.decode_aac_response.size = request.decode_aac_request.size; | ||||||
|  |         response.decode_aac_response.num_samples = 1024; // Just assume 1024 here
 | ||||||
|         return response; |         return response; | ||||||
|     default: |     default: | ||||||
|         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast<u16>(request.cmd)); |         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", | ||||||
|  |                   static_cast<u16>(request.header.cmd)); | ||||||
|         return std::nullopt; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -14,18 +14,22 @@ | ||||||
| namespace AudioCore::HLE { | namespace AudioCore::HLE { | ||||||
| 
 | 
 | ||||||
| enum class DecoderCommand : u16 { | enum class DecoderCommand : u16 { | ||||||
|     Init, |     Init = 0, | ||||||
|     Decode, |     EncodeDecode = 1, | ||||||
|     Unknown, |     Unknown = 2, // Probably UnInit
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum class DecoderCodec : u16 { | enum class DecoderCodec : u16 { | ||||||
|     None, |     None = 0, | ||||||
|     AAC, |     DecodeAAC = 1, | ||||||
|  |     EncodeAAC = 2, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | enum class ResultStatus : u32 { | ||||||
|  |     Success = 0, | ||||||
|  |     Error = 1, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // TODO(xperia64): I'm guessing that this is a u32 (from when it was an unknown)
 |  | ||||||
| // but it could be a u16 or u8 I suppose
 |  | ||||||
| enum class DecoderSampleRate : u32 { | enum class DecoderSampleRate : u32 { | ||||||
|     Rate48000 = 0, |     Rate48000 = 0, | ||||||
|     Rate44100 = 1, |     Rate44100 = 1, | ||||||
|  | @ -38,40 +42,96 @@ enum class DecoderSampleRate : u32 { | ||||||
|     Rate8000 = 8 |     Rate8000 = 8 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct BinaryRequest { | // The DSP replies with the same contents as the response too.
 | ||||||
|     enum_le<DecoderCodec> codec = | struct DecodeAACInitRequest { | ||||||
|         DecoderCodec::None; // this is a guess. until now only 0x1 was observed here
 |     u32_le unknown1 = 0; // observed 1 here
 | ||||||
|     enum_le<DecoderCommand> cmd = DecoderCommand::Init; |     u32_le unknown2 = 0; // observed -1 here
 | ||||||
|     u32_le fixed = 0; |     u32_le unknown3 = 0; // observed 1 here
 | ||||||
|  |     u32_le unknown4 = 0; // observed 0 here
 | ||||||
|  |     u32_le unknown5 = 0; // unused? observed 1 here
 | ||||||
|  |     u32_le unknown6 = 0; // unused? observed 0x20 here
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct DecodeAACRequest { | ||||||
|     u32_le src_addr = 0; |     u32_le src_addr = 0; | ||||||
|     u32_le size = 0; |     u32_le size = 0; | ||||||
|     u32_le dst_addr_ch0 = 0; |     u32_le dst_addr_ch0 = 0; | ||||||
|     u32_le dst_addr_ch1 = 0; |     u32_le dst_addr_ch1 = 0; | ||||||
|     u32_le unknown1 = 0; |     u32_le unknown1 = 0; // unused?
 | ||||||
|     u32_le unknown2 = 0; |     u32_le unknown2 = 0; // unused?
 | ||||||
| }; | }; | ||||||
| static_assert(sizeof(BinaryRequest) == 32, "Unexpected struct size for BinaryRequest"); |  | ||||||
| 
 | 
 | ||||||
| struct BinaryResponse { | struct DecodeAACResponse { | ||||||
|     enum_le<DecoderCodec> codec = |  | ||||||
|         DecoderCodec::None; // this could be something else. until now only 0x1 was observed here
 |  | ||||||
|     enum_le<DecoderCommand> cmd = DecoderCommand::Init; |  | ||||||
|     u32_le unknown1 = 0; |  | ||||||
|     enum_le<DecoderSampleRate> sample_rate; |     enum_le<DecoderSampleRate> sample_rate; | ||||||
|     u32_le num_channels = 0; // this is a guess, so far I only observed 2 here
 |     u32_le num_channels = 0; // this is a guess, so far I only observed 2 here
 | ||||||
|     u32_le size = 0; |     u32_le size = 0; | ||||||
|     u32_le unknown3 = 0; |     u32_le unknown1 = 0; | ||||||
|     u32_le unknown4 = 0; |     u32_le unknown2 = 0; | ||||||
|     u32_le num_samples = 0; // this is a guess, so far I only observed 1024 here
 |     u32_le num_samples = 0; // this is a guess, so far I only observed 1024 here
 | ||||||
| }; | }; | ||||||
| static_assert(sizeof(BinaryResponse) == 32, "Unexpected struct size for BinaryResponse"); | 
 | ||||||
|  | // The DSP replies with the same contents as the response too.
 | ||||||
|  | struct EncodeAACInitRequest { | ||||||
|  |     u32_le unknown1 = | ||||||
|  |         0; // 0:raw 1:ADTS? less than 2 according to the 3DS Sound app. observed 1 here
 | ||||||
|  |     enum_le<DecoderSampleRate> sample_rate = | ||||||
|  |         DecoderSampleRate::Rate16000; // the rate the 3DS Sound app uses
 | ||||||
|  |     u32_le unknown3 = | ||||||
|  |         0; // Num channels? less than 3 according to the 3DS Sound app. observed 2 here
 | ||||||
|  |     u32_le unknown4 = 0; // less than 2 according to the 3DS Sound app. observed 0 here
 | ||||||
|  |     u32_le unknown5 = 0; // unused?
 | ||||||
|  |     u32_le unknown6 = 0; // unused?
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct EncodeAACRequest { | ||||||
|  |     u32_le src_addr_ch0 = 0; | ||||||
|  |     u32_le src_addr_ch1 = 0; | ||||||
|  |     u32_le dst_addr = 0; | ||||||
|  |     u32_le unknown1 = 0; // the 3DS Sound app explicitly moves 0x003B'4A08, possibly an address
 | ||||||
|  |     u32_le unknown2 = 0; // unused?
 | ||||||
|  |     u32_le unknown3 = 0; // unused?
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct EncodeAACResponse { | ||||||
|  |     u32_le unknown1 = 0; | ||||||
|  |     u32_le unknown2 = 0; | ||||||
|  |     u32_le unknown3 = 0; | ||||||
|  |     u32_le unknown4 = 0; | ||||||
|  |     u32_le unknown5 = 0; // unused?
 | ||||||
|  |     u32_le unknown6 = 0; // unused?
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct BinaryMessage { | ||||||
|  |     struct { | ||||||
|  |         enum_le<DecoderCodec> codec = | ||||||
|  |             DecoderCodec::None; // this is a guess. until now only 0x1 was observed here
 | ||||||
|  |         enum_le<DecoderCommand> cmd = DecoderCommand::Init; | ||||||
|  |         // This is a guess, when tested with Init EncodeAAC, the DSP replies 0x0 for apparently
 | ||||||
|  |         // valid values and 0x1 (regardless of what was passed in the request) for invalid values in
 | ||||||
|  |         // other fields
 | ||||||
|  |         enum_le<ResultStatus> result = ResultStatus::Error; | ||||||
|  |     } header; | ||||||
|  |     union { | ||||||
|  |         std::array<u8, 24> data{}; | ||||||
|  | 
 | ||||||
|  |         DecodeAACInitRequest decode_aac_init; | ||||||
|  |         DecodeAACRequest decode_aac_request; | ||||||
|  |         DecodeAACResponse decode_aac_response; | ||||||
|  | 
 | ||||||
|  |         EncodeAACInitRequest encode_aac_init; | ||||||
|  |         EncodeAACRequest encode_aac_request; | ||||||
|  |         EncodeAACResponse encode_aac_response; | ||||||
|  |     }; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static_assert(sizeof(BinaryMessage) == 32, "Unexpected struct size for BinaryMessage"); | ||||||
| 
 | 
 | ||||||
| enum_le<DecoderSampleRate> GetSampleRateEnum(u32 sample_rate); | enum_le<DecoderSampleRate> GetSampleRateEnum(u32 sample_rate); | ||||||
| 
 | 
 | ||||||
| class DecoderBase { | class DecoderBase { | ||||||
| public: | public: | ||||||
|     virtual ~DecoderBase(); |     virtual ~DecoderBase(); | ||||||
|     virtual std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) = 0; |     virtual std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) = 0; | ||||||
|     /// Return true if this Decoder can be loaded. Return false if the system cannot create the
 |     /// Return true if this Decoder can be loaded. Return false if the system cannot create the
 | ||||||
|     /// decoder
 |     /// decoder
 | ||||||
|     virtual bool IsValid() const = 0; |     virtual bool IsValid() const = 0; | ||||||
|  | @ -81,7 +141,7 @@ class NullDecoder final : public DecoderBase { | ||||||
| public: | public: | ||||||
|     NullDecoder(); |     NullDecoder(); | ||||||
|     ~NullDecoder() override; |     ~NullDecoder() override; | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) override; | ||||||
|     bool IsValid() const override { |     bool IsValid() const override { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -11,15 +11,15 @@ class FDKDecoder::Impl { | ||||||
| public: | public: | ||||||
|     explicit Impl(Memory::MemorySystem& memory); |     explicit Impl(Memory::MemorySystem& memory); | ||||||
|     ~Impl(); |     ~Impl(); | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request); |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request); | ||||||
|     bool IsValid() const { |     bool IsValid() const { | ||||||
|         return decoder != nullptr; |         return decoder != nullptr; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     std::optional<BinaryResponse> Initalize(const BinaryRequest& request); |     std::optional<BinaryMessage> Initalize(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     std::optional<BinaryResponse> Decode(const BinaryRequest& request); |     std::optional<BinaryMessage> Decode(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     void Clear(); |     void Clear(); | ||||||
| 
 | 
 | ||||||
|  | @ -58,10 +58,9 @@ FDKDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> FDKDecoder::Impl::Initalize(const BinaryRequest& request) { | std::optional<BinaryMessage> FDKDecoder::Impl::Initalize(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response = request; | ||||||
|     std::memcpy(&response, &request, sizeof(response)); |     response.header.result = ResultStatus::Success; | ||||||
|     response.unknown1 = 0x0; |  | ||||||
| 
 | 
 | ||||||
|     if (decoder) { |     if (decoder) { | ||||||
|         LOG_INFO(Audio_DSP, "FDK Decoder initialized"); |         LOG_INFO(Audio_DSP, "FDK Decoder initialized"); | ||||||
|  | @ -90,56 +89,58 @@ void FDKDecoder::Impl::Clear() { | ||||||
|                                AACDEC_FLUSH & AACDEC_INTR & AACDEC_CONCEAL); |                                AACDEC_FLUSH & AACDEC_INTR & AACDEC_CONCEAL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> FDKDecoder::Impl::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> FDKDecoder::Impl::ProcessRequest(const BinaryMessage& request) { | ||||||
|     if (request.codec != DecoderCodec::AAC) { |     if (request.header.codec != DecoderCodec::DecodeAAC) { | ||||||
|         LOG_ERROR(Audio_DSP, "FDK AAC Decoder cannot handle such codec: {}", |         LOG_ERROR(Audio_DSP, "FDK AAC Decoder cannot handle such codec: {}", | ||||||
|                   static_cast<u16>(request.codec)); |                   static_cast<u16>(request.header.codec)); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (request.cmd) { |     switch (request.header.cmd) { | ||||||
|     case DecoderCommand::Init: { |     case DecoderCommand::Init: { | ||||||
|         return Initalize(request); |         return Initalize(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Decode: { |     case DecoderCommand::EncodeDecode: { | ||||||
|         return Decode(request); |         return Decode(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Unknown: { |     case DecoderCommand::Unknown: { | ||||||
|         BinaryResponse response; |         BinaryMessage response = request; | ||||||
|         std::memcpy(&response, &request, sizeof(response)); |         response.header.result = 0x0; | ||||||
|         response.unknown1 = 0x0; |  | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|     default: |     default: | ||||||
|         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast<u16>(request.cmd)); |         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", | ||||||
|  |                   static_cast<u16>(request.header.cmd)); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> FDKDecoder::Impl::Decode(const BinaryRequest& request) { | std::optional<BinaryMessage> FDKDecoder::Impl::Decode(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessages response; | ||||||
|     response.codec = request.codec; |     response.header.codec = request.header.codec; | ||||||
|     response.cmd = request.cmd; |     response.header.cmd = request.header.cmd; | ||||||
|     response.size = request.size; |     response.decode_aac_response.size = request.decode_aac_request.size; | ||||||
| 
 | 
 | ||||||
|     if (!decoder) { |     if (!decoder) { | ||||||
|         LOG_DEBUG(Audio_DSP, "Decoder not initalized"); |         LOG_DEBUG(Audio_DSP, "Decoder not initalized"); | ||||||
|         // This is a hack to continue games that are not compiled with the aac codec
 |         // This is a hack to continue games that are not compiled with the aac codec
 | ||||||
|         response.num_channels = 2; |         response.decode_aac_response.num_channels = 2; | ||||||
|         response.num_samples = 1024; |         response.decode_aac_response.num_samples = 1024; | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (request.src_addr < Memory::FCRAM_PADDR || |     if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || | ||||||
|         request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |         request.decode_aac_request.src_addr + request.size > | ||||||
|         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); |             Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  |         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", | ||||||
|  |                   request.decode_aac_request.src_addr); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
|     u8* data = memory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); |     u8* data = memory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); | ||||||
| 
 | 
 | ||||||
|     std::array<std::vector<s16>, 2> out_streams; |     std::array<std::vector<s16>, 2> out_streams; | ||||||
| 
 | 
 | ||||||
|     std::size_t data_size = request.size; |     std::size_t data_size = request.decode_aac_request.size; | ||||||
| 
 | 
 | ||||||
|     // decoding loops
 |     // decoding loops
 | ||||||
|     AAC_DECODER_ERROR result = AAC_DEC_OK; |     AAC_DECODER_ERROR result = AAC_DEC_OK; | ||||||
|  | @ -168,9 +169,9 @@ std::optional<BinaryResponse> FDKDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
|             // get the stream information
 |             // get the stream information
 | ||||||
|             stream_info = aacDecoder_GetStreamInfo(decoder); |             stream_info = aacDecoder_GetStreamInfo(decoder); | ||||||
|             // fill the stream information for binary response
 |             // fill the stream information for binary response
 | ||||||
|             response.sample_rate = GetSampleRateEnum(stream_info->sampleRate); |             response.decode_aac_response.sample_rate = GetSampleRateEnum(stream_info->sampleRate); | ||||||
|             response.num_channels = stream_info->numChannels; |             response.decode_aac_response.num_channels = stream_info->numChannels; | ||||||
|             response.num_samples = stream_info->frameSize; |             response.decode_aac_response.num_samples = stream_info->frameSize; | ||||||
|             // fill the output
 |             // fill the output
 | ||||||
|             // the sample size = frame_size * channel_counts
 |             // the sample size = frame_size * channel_counts
 | ||||||
|             for (int sample = 0; sample < stream_info->frameSize; sample++) { |             for (int sample = 0; sample < stream_info->frameSize; sample++) { | ||||||
|  | @ -193,7 +194,8 @@ std::optional<BinaryResponse> FDKDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
|     for (std::size_t ch = 0; ch < out_streams.size(); ch++) { |     for (std::size_t ch = 0; ch < out_streams.size(); ch++) { | ||||||
|         if (!out_streams[ch].empty()) { |         if (!out_streams[ch].empty()) { | ||||||
|             auto byte_size = out_streams[ch].size() * sizeof(s16); |             auto byte_size = out_streams[ch].size() * sizeof(s16); | ||||||
|             auto dst = ch == 0 ? request.dst_addr_ch0 : request.dst_addr_ch1; |             auto dst = ch == 0 ? request.decode_aac_request.dst_addr_ch0 | ||||||
|  |                                : request.decode_aac_request.dst_addr_ch1; | ||||||
|             if (dst < Memory::FCRAM_PADDR || |             if (dst < Memory::FCRAM_PADDR || | ||||||
|                 dst + byte_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |                 dst + byte_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|                 LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch{} {:08x}", ch, dst); |                 LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch{} {:08x}", ch, dst); | ||||||
|  | @ -211,7 +213,7 @@ FDKDecoder::FDKDecoder(Memory::MemorySystem& memory) : impl(std::make_unique<Imp | ||||||
| 
 | 
 | ||||||
| FDKDecoder::~FDKDecoder() = default; | FDKDecoder::~FDKDecoder() = default; | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> FDKDecoder::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> FDKDecoder::ProcessRequest(const BinaryMessage& request) { | ||||||
|     return impl->ProcessRequest(request); |     return impl->ProcessRequest(request); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ class FDKDecoder final : public DecoderBase { | ||||||
| public: | public: | ||||||
|     explicit FDKDecoder(Memory::MemorySystem& memory); |     explicit FDKDecoder(Memory::MemorySystem& memory); | ||||||
|     ~FDKDecoder() override; |     ~FDKDecoder() override; | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) override; | ||||||
|     bool IsValid() const override; |     bool IsValid() const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |  | ||||||
|  | @ -11,17 +11,17 @@ class FFMPEGDecoder::Impl { | ||||||
| public: | public: | ||||||
|     explicit Impl(Memory::MemorySystem& memory); |     explicit Impl(Memory::MemorySystem& memory); | ||||||
|     ~Impl(); |     ~Impl(); | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request); |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request); | ||||||
|     bool IsValid() const { |     bool IsValid() const { | ||||||
|         return have_ffmpeg_dl; |         return have_ffmpeg_dl; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     std::optional<BinaryResponse> Initalize(const BinaryRequest& request); |     std::optional<BinaryMessage> Initalize(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     void Clear(); |     void Clear(); | ||||||
| 
 | 
 | ||||||
|     std::optional<BinaryResponse> Decode(const BinaryRequest& request); |     std::optional<BinaryMessage> Decode(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     struct AVPacketDeleter { |     struct AVPacketDeleter { | ||||||
|         void operator()(AVPacket* packet) const { |         void operator()(AVPacket* packet) const { | ||||||
|  | @ -65,9 +65,9 @@ FFMPEGDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { | ||||||
| 
 | 
 | ||||||
| FFMPEGDecoder::Impl::~Impl() = default; | FFMPEGDecoder::Impl::~Impl() = default; | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> FFMPEGDecoder::Impl::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> FFMPEGDecoder::Impl::ProcessRequest(const BinaryMessage& request) { | ||||||
|     if (request.codec != DecoderCodec::AAC) { |     if (request.codec != DecoderCodec::DecodeAAC) { | ||||||
|         LOG_ERROR(Audio_DSP, "Got wrong codec {}", static_cast<u16>(request.codec)); |         LOG_ERROR(Audio_DSP, "Got wrong codec {}", static_cast<u16>(request.header.codec)); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -79,25 +79,24 @@ std::optional<BinaryResponse> FFMPEGDecoder::Impl::ProcessRequest(const BinaryRe | ||||||
|         return Decode(request); |         return Decode(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Unknown: { |     case DecoderCommand::Unknown: { | ||||||
|         BinaryResponse response; |         BinaryMessage response = request; | ||||||
|         std::memcpy(&response, &request, sizeof(response)); |         response.header.result = ResultStatus::Success; | ||||||
|         response.unknown1 = 0x0; |  | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|     default: |     default: | ||||||
|         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast<u16>(request.cmd)); |         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", | ||||||
|  |                   static_cast<u16>(request.header.cmd)); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> FFMPEGDecoder::Impl::Initalize(const BinaryRequest& request) { | std::optional<BinaryMessage> FFMPEGDecoder::Impl::Initalize(const BinaryMessage& request) { | ||||||
|     if (initalized) { |     if (initalized) { | ||||||
|         Clear(); |         Clear(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     BinaryResponse response; |     BinaryMessage response = request; | ||||||
|     std::memcpy(&response, &request, sizeof(response)); |     response.header.result = ResultStatus::Success; | ||||||
|     response.unknown1 = 0x0; |  | ||||||
| 
 | 
 | ||||||
|     if (!have_ffmpeg_dl) { |     if (!have_ffmpeg_dl) { | ||||||
|         return response; |         return response; | ||||||
|  | @ -143,30 +142,32 @@ void FFMPEGDecoder::Impl::Clear() { | ||||||
|     av_packet.reset(); |     av_packet.reset(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> FFMPEGDecoder::Impl::Decode(const BinaryRequest& request) { | std::optional<BinaryMessage> FFMPEGDecoder::Impl::Decode(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response; | ||||||
|     response.codec = request.codec; |     response.header.codec = request.header.codec; | ||||||
|     response.cmd = request.cmd; |     response.header.cmd = request.header.cmd; | ||||||
|     response.size = request.size; |     response.decode_aac_response.size = request.decode_aac_request.size; | ||||||
| 
 | 
 | ||||||
|     if (!initalized) { |     if (!initalized) { | ||||||
|         LOG_DEBUG(Audio_DSP, "Decoder not initalized"); |         LOG_DEBUG(Audio_DSP, "Decoder not initalized"); | ||||||
|         // This is a hack to continue games that are not compiled with the aac codec
 |         // This is a hack to continue games that are not compiled with the aac codec
 | ||||||
|         response.num_channels = 2; |         response.decode_aac_response.num_channels = 2; | ||||||
|         response.num_samples = 1024; |         response.decode_aac_response.num_samples = 1024; | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (request.src_addr < Memory::FCRAM_PADDR || |     if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || | ||||||
|         request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |         request.decode_aac_request.src_addr + request.decode_aac_request.size > | ||||||
|         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); |             Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  |         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", | ||||||
|  |                   request.decode_aac_request.src_addr); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
|     u8* data = memory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); |     u8* data = memory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); | ||||||
| 
 | 
 | ||||||
|     std::array<std::vector<u8>, 2> out_streams; |     std::array<std::vector<u8>, 2> out_streams; | ||||||
| 
 | 
 | ||||||
|     std::size_t data_size = request.size; |     std::size_t data_size = request.decode_aac_request.size; | ||||||
|     while (data_size > 0) { |     while (data_size > 0) { | ||||||
|         if (!decoded_frame) { |         if (!decoded_frame) { | ||||||
|             decoded_frame.reset(av_frame_alloc_dl()); |             decoded_frame.reset(av_frame_alloc_dl()); | ||||||
|  | @ -211,9 +212,10 @@ std::optional<BinaryResponse> FFMPEGDecoder::Impl::Decode(const BinaryRequest& r | ||||||
| 
 | 
 | ||||||
|                 std::size_t size = bytes_per_sample * (decoded_frame->nb_samples); |                 std::size_t size = bytes_per_sample * (decoded_frame->nb_samples); | ||||||
| 
 | 
 | ||||||
|                 response.sample_rate = GetSampleRateEnum(decoded_frame->sample_rate); |                 response.decode_aac_response.sample_rate = | ||||||
|                 response.num_channels = decoded_frame->channels; |                     GetSampleRateEnum(decoded_frame->sample_rate); | ||||||
|                 response.num_samples += decoded_frame->nb_samples; |                 response.decode_aac_response.num_channels = decoded_frame->channels; | ||||||
|  |                 response.decode_aac_response.num_samples += decoded_frame->nb_samples; | ||||||
| 
 | 
 | ||||||
|                 // FFmpeg converts to 32 signed floating point PCM, we need s16 PCM so we need to
 |                 // FFmpeg converts to 32 signed floating point PCM, we need s16 PCM so we need to
 | ||||||
|                 // convert it
 |                 // convert it
 | ||||||
|  | @ -234,24 +236,28 @@ std::optional<BinaryResponse> FFMPEGDecoder::Impl::Decode(const BinaryRequest& r | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (out_streams[0].size() != 0) { |     if (out_streams[0].size() != 0) { | ||||||
|         if (request.dst_addr_ch0 < Memory::FCRAM_PADDR || |         if (request.decode_aac_request.dst_addr_ch0 < Memory::FCRAM_PADDR || | ||||||
|             request.dst_addr_ch0 + out_streams[0].size() > |             request.decode_aac_request.dst_addr_ch0 + out_streams[0].size() > | ||||||
|                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", request.dst_addr_ch0); |             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", | ||||||
|  |                       request.decode_aac_request.dst_addr_ch0); | ||||||
|             return {}; |             return {}; | ||||||
|         } |         } | ||||||
|         std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch0 - Memory::FCRAM_PADDR), |         std::memcpy( | ||||||
|  |             memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch0 - Memory::FCRAM_PADDR), | ||||||
|             out_streams[0].data(), out_streams[0].size()); |             out_streams[0].data(), out_streams[0].size()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (out_streams[1].size() != 0) { |     if (out_streams[1].size() != 0) { | ||||||
|         if (request.dst_addr_ch1 < Memory::FCRAM_PADDR || |         if (request.decode_aac_request.dst_addr_ch1 < Memory::FCRAM_PADDR || | ||||||
|             request.dst_addr_ch1 + out_streams[1].size() > |             request.decode_aac_request.dst_addr_ch1 + out_streams[1].size() > | ||||||
|                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", request.dst_addr_ch1); |             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", | ||||||
|  |                       request.decode_aac_request.dst_addr_ch1); | ||||||
|             return {}; |             return {}; | ||||||
|         } |         } | ||||||
|         std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), |         std::memcpy( | ||||||
|  |             memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch1 - Memory::FCRAM_PADDR), | ||||||
|             out_streams[1].data(), out_streams[1].size()); |             out_streams[1].data(), out_streams[1].size()); | ||||||
|     } |     } | ||||||
|     return response; |     return response; | ||||||
|  | @ -261,7 +267,7 @@ FFMPEGDecoder::FFMPEGDecoder(Memory::MemorySystem& memory) : impl(std::make_uniq | ||||||
| 
 | 
 | ||||||
| FFMPEGDecoder::~FFMPEGDecoder() = default; | FFMPEGDecoder::~FFMPEGDecoder() = default; | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> FFMPEGDecoder::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> FFMPEGDecoder::ProcessRequest(const BinaryMessage& request) { | ||||||
|     return impl->ProcessRequest(request); |     return impl->ProcessRequest(request); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ class FFMPEGDecoder final : public DecoderBase { | ||||||
| public: | public: | ||||||
|     explicit FFMPEGDecoder(Memory::MemorySystem& memory); |     explicit FFMPEGDecoder(Memory::MemorySystem& memory); | ||||||
|     ~FFMPEGDecoder() override; |     ~FFMPEGDecoder() override; | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) override; | ||||||
|     bool IsValid() const override; |     bool IsValid() const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |  | ||||||
|  | @ -40,7 +40,8 @@ using Service::DSP::DSP_DSP; | ||||||
| 
 | 
 | ||||||
| namespace AudioCore { | namespace AudioCore { | ||||||
| 
 | 
 | ||||||
| DspHle::DspHle() : DspHle(Core::System::GetInstance().Memory(), Core::System::GetInstance().CoreTiming()) {} | DspHle::DspHle() | ||||||
|  |     : DspHle(Core::System::GetInstance().Memory(), Core::System::GetInstance().CoreTiming()) {} | ||||||
| 
 | 
 | ||||||
| template <class Archive> | template <class Archive> | ||||||
| void DspHle::serialize(Archive& ar, const unsigned int) { | void DspHle::serialize(Archive& ar, const unsigned int) { | ||||||
|  | @ -291,21 +292,21 @@ void DspHle::Impl::PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) | ||||||
|     } |     } | ||||||
|     case DspPipe::Binary: { |     case DspPipe::Binary: { | ||||||
|         // TODO(B3N30): Make this async, and signal the interrupt
 |         // TODO(B3N30): Make this async, and signal the interrupt
 | ||||||
|         HLE::BinaryRequest request; |         HLE::BinaryMessage request{}; | ||||||
|         if (sizeof(request) != buffer.size()) { |         if (sizeof(request) != buffer.size()) { | ||||||
|             LOG_CRITICAL(Audio_DSP, "got binary pipe with wrong size {}", buffer.size()); |             LOG_CRITICAL(Audio_DSP, "got binary pipe with wrong size {}", buffer.size()); | ||||||
|             UNIMPLEMENTED(); |             UNIMPLEMENTED(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         std::memcpy(&request, buffer.data(), buffer.size()); |         std::memcpy(&request, buffer.data(), buffer.size()); | ||||||
|         if (request.codec != HLE::DecoderCodec::AAC) { |         if (request.header.codec != HLE::DecoderCodec::DecodeAAC) { | ||||||
|             LOG_CRITICAL(Audio_DSP, "got unknown codec {}", static_cast<u16>(request.codec)); |             LOG_CRITICAL(Audio_DSP, "got unknown codec {}", static_cast<u16>(request.header.codec)); | ||||||
|             UNIMPLEMENTED(); |             UNIMPLEMENTED(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         std::optional<HLE::BinaryResponse> response = decoder->ProcessRequest(request); |         std::optional<HLE::BinaryMessage> response = decoder->ProcessRequest(request); | ||||||
|         if (response) { |         if (response) { | ||||||
|             const HLE::BinaryResponse& value = *response; |             const HLE::BinaryMessage& value = *response; | ||||||
|             pipe_data[static_cast<u32>(pipe_number)].resize(sizeof(value)); |             pipe_data[static_cast<u32>(pipe_number)].resize(sizeof(value)); | ||||||
|             std::memcpy(pipe_data[static_cast<u32>(pipe_number)].data(), &value, sizeof(value)); |             std::memcpy(pipe_data[static_cast<u32>(pipe_number)].data(), &value, sizeof(value)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -25,16 +25,16 @@ class MediaNDKDecoder::Impl { | ||||||
| public: | public: | ||||||
|     explicit Impl(Memory::MemorySystem& memory); |     explicit Impl(Memory::MemorySystem& memory); | ||||||
|     ~Impl(); |     ~Impl(); | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request); |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     bool SetMediaType(const ADTSData& adts_data); |     bool SetMediaType(const ADTSData& adts_data); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     std::optional<BinaryResponse> Initalize(const BinaryRequest& request); |     std::optional<BinaryMessage> Initalize(const BinaryMessage& request); | ||||||
|     std::optional<BinaryResponse> Decode(const BinaryRequest& request); |     std::optional<BinaryMessage> Decode(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     Memory::MemorySystem& mMemory; |     Memory::MemorySystem& memory; | ||||||
|     std::unique_ptr<AMediaCodec, AMediaCodecRelease> mDecoder; |     std::unique_ptr<AMediaCodec, AMediaCodecRelease> decoder; | ||||||
|     // default: 2 channles, 48000 samplerate
 |     // default: 2 channles, 48000 samplerate
 | ||||||
|     ADTSData mADTSData{ |     ADTSData mADTSData{ | ||||||
|         /*header_length*/ 7,  /*MPEG2*/ false,   /*profile*/ 2, |         /*header_length*/ 7,  /*MPEG2*/ false,   /*profile*/ 2, | ||||||
|  | @ -42,28 +42,27 @@ private: | ||||||
|         /*samplerate_idx*/ 3, /*length*/ 0,      /*samplerate*/ 48000}; |         /*samplerate_idx*/ 3, /*length*/ 0,      /*samplerate*/ 48000}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| MediaNDKDecoder::Impl::Impl(Memory::MemorySystem& memory) : mMemory(memory) { | MediaNDKDecoder::Impl::Impl(Memory::MemorySystem& memory_) : memory(memory_) { | ||||||
|     SetMediaType(mADTSData); |     SetMediaType(mADTSData); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MediaNDKDecoder::Impl::~Impl() = default; | MediaNDKDecoder::Impl::~Impl() = default; | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> MediaNDKDecoder::Impl::Initalize(const BinaryRequest& request) { | std::optional<BinaryMessage> MediaNDKDecoder::Impl::Initalize(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response = request; | ||||||
|     std::memcpy(&response, &request, sizeof(response)); |     response.header.result = ResultStatus::Success; | ||||||
|     response.unknown1 = 0x0; |  | ||||||
|     return response; |     return response; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool MediaNDKDecoder::Impl::SetMediaType(const ADTSData& adts_data) { | bool MediaNDKDecoder::Impl::SetMediaType(const ADTSData& adts_data) { | ||||||
|     const char* mime = "audio/mp4a-latm"; |     const char* mime = "audio/mp4a-latm"; | ||||||
|     if (mDecoder && mADTSData.profile == adts_data.profile && |     if (decoder && mADTSData.profile == adts_data.profile && | ||||||
|         mADTSData.channel_idx == adts_data.channel_idx && |         mADTSData.channel_idx == adts_data.channel_idx && | ||||||
|         mADTSData.samplerate_idx == adts_data.samplerate_idx) { |         mADTSData.samplerate_idx == adts_data.samplerate_idx) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|     mDecoder.reset(AMediaCodec_createDecoderByType(mime)); |     decoder.reset(AMediaCodec_createDecoderByType(mime)); | ||||||
|     if (mDecoder == nullptr) { |     if (decoder == nullptr) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -78,17 +77,17 @@ bool MediaNDKDecoder::Impl::SetMediaType(const ADTSData& adts_data) { | ||||||
|     AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_IS_ADTS, 1); |     AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_IS_ADTS, 1); | ||||||
|     AMediaFormat_setBuffer(format, "csd-0", csd_0, sizeof(csd_0)); |     AMediaFormat_setBuffer(format, "csd-0", csd_0, sizeof(csd_0)); | ||||||
| 
 | 
 | ||||||
|     media_status_t status = AMediaCodec_configure(mDecoder.get(), format, NULL, NULL, 0); |     media_status_t status = AMediaCodec_configure(decoder.get(), format, NULL, NULL, 0); | ||||||
|     if (status != AMEDIA_OK) { |     if (status != AMEDIA_OK) { | ||||||
|         AMediaFormat_delete(format); |         AMediaFormat_delete(format); | ||||||
|         mDecoder.reset(); |         decoder.reset(); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     status = AMediaCodec_start(mDecoder.get()); |     status = AMediaCodec_start(decoder.get()); | ||||||
|     if (status != AMEDIA_OK) { |     if (status != AMEDIA_OK) { | ||||||
|         AMediaFormat_delete(format); |         AMediaFormat_delete(format); | ||||||
|         mDecoder.reset(); |         decoder.reset(); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -97,51 +96,53 @@ bool MediaNDKDecoder::Impl::SetMediaType(const ADTSData& adts_data) { | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> MediaNDKDecoder::Impl::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> MediaNDKDecoder::Impl::ProcessRequest(const BinaryMessage& request) { | ||||||
|     if (request.codec != DecoderCodec::AAC) { |     if (request.header.codec != DecoderCodec::DecodeAAC) { | ||||||
|         LOG_ERROR(Audio_DSP, "AAC Decoder cannot handle such codec: {}", |         LOG_ERROR(Audio_DSP, "AAC Decoder cannot handle such codec: {}", | ||||||
|                   static_cast<u16>(request.codec)); |                   static_cast<u16>(request.header.codec)); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (request.cmd) { |     switch (request.header.cmd) { | ||||||
|     case DecoderCommand::Init: { |     case DecoderCommand::Init: { | ||||||
|         return Initalize(request); |         return Initalize(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Decode: { |     case DecoderCommand::EncodeDecode: { | ||||||
|         return Decode(request); |         return Decode(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Unknown: { |     case DecoderCommand::Unknown: { | ||||||
|         BinaryResponse response; |         BinaryMessage response = request; | ||||||
|         std::memcpy(&response, &request, sizeof(response)); |         response.header.result = ResultStatus::Success; | ||||||
|         response.unknown1 = 0x0; |  | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|     default: |     default: | ||||||
|         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast<u16>(request.cmd)); |         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", | ||||||
|  |                   static_cast<u16>(request.header.cmd)); | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> MediaNDKDecoder::Impl::Decode(const BinaryRequest& request) { | std::optional<BinaryMessage> MediaNDKDecoder::Impl::Decode(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response{}; | ||||||
|     response.codec = request.codec; |     response.header.codec = request.header.codec; | ||||||
|     response.cmd = request.cmd; |     response.header.cmd = request.header.cmd; | ||||||
|     response.size = request.size; |     response.decode_aac_response.size = request.decode_aac_request.size; | ||||||
|     response.num_samples = 1024; |     response.decode_aac_response.num_samples = 1024; | ||||||
| 
 | 
 | ||||||
|     if (request.src_addr < Memory::FCRAM_PADDR || |     if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || | ||||||
|         request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |         request.decode_aac_request.src_addr + request.decode_aac_request.size > | ||||||
|         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); |             Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  |         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", | ||||||
|  |                   request.decode_aac_request.src_addr); | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     u8* data = mMemory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); |     u8* data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR); | ||||||
|     ADTSData adts_data = ParseADTS(reinterpret_cast<const char*>(data)); |     ADTSData adts_data = ParseADTS(reinterpret_cast<const char*>(data)); | ||||||
|     SetMediaType(adts_data); |     SetMediaType(adts_data); | ||||||
|     response.sample_rate = GetSampleRateEnum(adts_data.samplerate); |     response.decode_aac_response.sample_rate = GetSampleRateEnum(adts_data.samplerate); | ||||||
|     response.num_channels = adts_data.channels; |     response.decode_aac_response.num_channels = adts_data.channels; | ||||||
|     if (!mDecoder) { |     if (!decoder) { | ||||||
|         LOG_ERROR(Audio_DSP, "Missing decoder for profile: {}, channels: {}, samplerate: {}", |         LOG_ERROR(Audio_DSP, "Missing decoder for profile: {}, channels: {}, samplerate: {}", | ||||||
|                   adts_data.profile, adts_data.channels, adts_data.samplerate); |                   adts_data.profile, adts_data.channels, adts_data.samplerate); | ||||||
|         return {}; |         return {}; | ||||||
|  | @ -151,18 +152,18 @@ std::optional<BinaryResponse> MediaNDKDecoder::Impl::Decode(const BinaryRequest& | ||||||
|     constexpr int timeout = 160; |     constexpr int timeout = 160; | ||||||
|     std::size_t buffer_size = 0; |     std::size_t buffer_size = 0; | ||||||
|     u8* buffer = nullptr; |     u8* buffer = nullptr; | ||||||
|     ssize_t buffer_index = AMediaCodec_dequeueInputBuffer(mDecoder.get(), timeout); |     ssize_t buffer_index = AMediaCodec_dequeueInputBuffer(decoder.get(), timeout); | ||||||
|     if (buffer_index < 0) { |     if (buffer_index < 0) { | ||||||
|         LOG_ERROR(Audio_DSP, "Failed to enqueue the input samples: {}", buffer_index); |         LOG_ERROR(Audio_DSP, "Failed to enqueue the input samples: {}", buffer_index); | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|     buffer = AMediaCodec_getInputBuffer(mDecoder.get(), buffer_index, &buffer_size); |     buffer = AMediaCodec_getInputBuffer(decoder.get(), buffer_index, &buffer_size); | ||||||
|     if (buffer_size < request.size) { |     if (buffer_size < request.decode_aac_request.size) { | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|     std::memcpy(buffer, data, request.size); |     std::memcpy(buffer, data, request.decode_aac_request.size); | ||||||
|     media_status_t status = |     media_status_t status = AMediaCodec_queueInputBuffer(decoder.get(), buffer_index, 0, | ||||||
|         AMediaCodec_queueInputBuffer(mDecoder.get(), buffer_index, 0, request.size, 0, 0); |                                                          request.decode_aac_request.size, 0, 0); | ||||||
|     if (status != AMEDIA_OK) { |     if (status != AMEDIA_OK) { | ||||||
|         LOG_WARNING(Audio_DSP, "Try queue input buffer again later!"); |         LOG_WARNING(Audio_DSP, "Try queue input buffer again later!"); | ||||||
|         return response; |         return response; | ||||||
|  | @ -171,7 +172,7 @@ std::optional<BinaryResponse> MediaNDKDecoder::Impl::Decode(const BinaryRequest& | ||||||
|     // output
 |     // output
 | ||||||
|     AMediaCodecBufferInfo info; |     AMediaCodecBufferInfo info; | ||||||
|     std::array<std::vector<u16>, 2> out_streams; |     std::array<std::vector<u16>, 2> out_streams; | ||||||
|     buffer_index = AMediaCodec_dequeueOutputBuffer(mDecoder.get(), &info, timeout); |     buffer_index = AMediaCodec_dequeueOutputBuffer(decoder.get(), &info, timeout); | ||||||
|     switch (buffer_index) { |     switch (buffer_index) { | ||||||
|     case AMEDIACODEC_INFO_TRY_AGAIN_LATER: |     case AMEDIACODEC_INFO_TRY_AGAIN_LATER: | ||||||
|         LOG_WARNING(Audio_DSP, "Failed to dequeue output buffer: timeout!"); |         LOG_WARNING(Audio_DSP, "Failed to dequeue output buffer: timeout!"); | ||||||
|  | @ -180,46 +181,52 @@ std::optional<BinaryResponse> MediaNDKDecoder::Impl::Decode(const BinaryRequest& | ||||||
|         LOG_WARNING(Audio_DSP, "Failed to dequeue output buffer: buffers changed!"); |         LOG_WARNING(Audio_DSP, "Failed to dequeue output buffer: buffers changed!"); | ||||||
|         break; |         break; | ||||||
|     case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED: { |     case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED: { | ||||||
|         AMediaFormat* format = AMediaCodec_getOutputFormat(mDecoder.get()); |         AMediaFormat* format = AMediaCodec_getOutputFormat(decoder.get()); | ||||||
|         LOG_WARNING(Audio_DSP, "output format: {}", AMediaFormat_toString(format)); |         LOG_WARNING(Audio_DSP, "output format: {}", AMediaFormat_toString(format)); | ||||||
|         AMediaFormat_delete(format); |         AMediaFormat_delete(format); | ||||||
|         buffer_index = AMediaCodec_dequeueOutputBuffer(mDecoder.get(), &info, timeout); |         buffer_index = AMediaCodec_dequeueOutputBuffer(decoder.get(), &info, timeout); | ||||||
|     } |     } | ||||||
|     default: { |     default: { | ||||||
|         int offset = info.offset; |         int offset = info.offset; | ||||||
|         buffer = AMediaCodec_getOutputBuffer(mDecoder.get(), buffer_index, &buffer_size); |         buffer = AMediaCodec_getOutputBuffer(decoder.get(), buffer_index, &buffer_size); | ||||||
|         while (offset < info.size) { |         while (offset < info.size) { | ||||||
|             for (int channel = 0; channel < response.num_channels; channel++) { |             for (int channel = 0; channel < response.decode_aac_response.num_channels; channel++) { | ||||||
|                 u16 pcm_data; |                 u16 pcm_data; | ||||||
|                 std::memcpy(&pcm_data, buffer + offset, sizeof(pcm_data)); |                 std::memcpy(&pcm_data, buffer + offset, sizeof(pcm_data)); | ||||||
|                 out_streams[channel].push_back(pcm_data); |                 out_streams[channel].push_back(pcm_data); | ||||||
|                 offset += sizeof(pcm_data); |                 offset += sizeof(pcm_data); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         AMediaCodec_releaseOutputBuffer(mDecoder.get(), buffer_index, info.size != 0); |         AMediaCodec_releaseOutputBuffer(decoder.get(), buffer_index, info.size != 0); | ||||||
|     } |     } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // transfer the decoded buffer from vector to the FCRAM
 |     // transfer the decoded buffer from vector to the FCRAM
 | ||||||
|     size_t stream0_size = out_streams[0].size() * sizeof(u16); |     size_t stream0_size = out_streams[0].size() * sizeof(u16); | ||||||
|     if (stream0_size != 0) { |     if (stream0_size != 0) { | ||||||
|         if (request.dst_addr_ch0 < Memory::FCRAM_PADDR || |         if (request.decode_aac_request.dst_addr_ch0 < Memory::FCRAM_PADDR || | ||||||
|             request.dst_addr_ch0 + stream0_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |             request.decode_aac_request.dst_addr_ch0 + stream0_size > | ||||||
|             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", request.dst_addr_ch0); |                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  |             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", | ||||||
|  |                       request.decode_aac_request.dst_addr_ch0); | ||||||
|             return response; |             return response; | ||||||
|         } |         } | ||||||
|         std::memcpy(mMemory.GetFCRAMPointer(request.dst_addr_ch0 - Memory::FCRAM_PADDR), |         std::memcpy( | ||||||
|  |             memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch0 - Memory::FCRAM_PADDR), | ||||||
|             out_streams[0].data(), stream0_size); |             out_streams[0].data(), stream0_size); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     size_t stream1_size = out_streams[1].size() * sizeof(u16); |     size_t stream1_size = out_streams[1].size() * sizeof(u16); | ||||||
|     if (stream1_size != 0) { |     if (stream1_size != 0) { | ||||||
|         if (request.dst_addr_ch1 < Memory::FCRAM_PADDR || |         if (request.decode_aac_request.dst_addr_ch1 < Memory::FCRAM_PADDR || | ||||||
|             request.dst_addr_ch1 + stream1_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |             request.decode_aac_request.dst_addr_ch1 + stream1_size > | ||||||
|             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", request.dst_addr_ch1); |                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  |             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", | ||||||
|  |                       request.decode_aac_request.dst_addr_ch1); | ||||||
|             return response; |             return response; | ||||||
|         } |         } | ||||||
|         std::memcpy(mMemory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), |         std::memcpy( | ||||||
|  |             memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch1 - Memory::FCRAM_PADDR), | ||||||
|             out_streams[1].data(), stream1_size); |             out_streams[1].data(), stream1_size); | ||||||
|     } |     } | ||||||
|     return response; |     return response; | ||||||
|  | @ -230,7 +237,7 @@ MediaNDKDecoder::MediaNDKDecoder(Memory::MemorySystem& memory) | ||||||
| 
 | 
 | ||||||
| MediaNDKDecoder::~MediaNDKDecoder() = default; | MediaNDKDecoder::~MediaNDKDecoder() = default; | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> MediaNDKDecoder::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> MediaNDKDecoder::ProcessRequest(const BinaryMessage& request) { | ||||||
|     return impl->ProcessRequest(request); |     return impl->ProcessRequest(request); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ class MediaNDKDecoder final : public DecoderBase { | ||||||
| public: | public: | ||||||
|     explicit MediaNDKDecoder(Memory::MemorySystem& memory); |     explicit MediaNDKDecoder(Memory::MemorySystem& memory); | ||||||
|     ~MediaNDKDecoder() override; |     ~MediaNDKDecoder() override; | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) override; | ||||||
|     bool IsValid() const override; |     bool IsValid() const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |  | ||||||
|  | @ -13,15 +13,15 @@ class WMFDecoder::Impl { | ||||||
| public: | public: | ||||||
|     explicit Impl(Memory::MemorySystem& memory); |     explicit Impl(Memory::MemorySystem& memory); | ||||||
|     ~Impl(); |     ~Impl(); | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request); |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request); | ||||||
|     bool IsValid() const { |     bool IsValid() const { | ||||||
|         return is_valid; |         return is_valid; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     std::optional<BinaryResponse> Initalize(const BinaryRequest& request); |     std::optional<BinaryMessage> Initalize(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     std::optional<BinaryResponse> Decode(const BinaryRequest& request); |     std::optional<BinaryMessage> Decode(const BinaryMessage& request); | ||||||
| 
 | 
 | ||||||
|     MFOutputState DecodingLoop(ADTSData adts_header, std::array<std::vector<u8>, 2>& out_streams); |     MFOutputState DecodingLoop(ADTSData adts_header, std::array<std::vector<u8>, 2>& out_streams); | ||||||
| 
 | 
 | ||||||
|  | @ -101,36 +101,35 @@ WMFDecoder::Impl::~Impl() { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> WMFDecoder::Impl::ProcessRequest(const BinaryMessage& request) { | ||||||
|     if (request.codec != DecoderCodec::AAC) { |     if (request.header.codec != DecoderCodec::DecodeAAC) { | ||||||
|         LOG_ERROR(Audio_DSP, "Got unknown codec {}", static_cast<u16>(request.codec)); |         LOG_ERROR(Audio_DSP, "Got unknown codec {}", static_cast<u16>(request.header.codec)); | ||||||
|         return std::nullopt; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (request.cmd) { |     switch (request.header.cmd) { | ||||||
|     case DecoderCommand::Init: { |     case DecoderCommand::Init: { | ||||||
|         LOG_INFO(Audio_DSP, "WMFDecoder initializing"); |         LOG_INFO(Audio_DSP, "WMFDecoder initializing"); | ||||||
|         return Initalize(request); |         return Initalize(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Decode: { |     case DecoderCommand::EncodeDecode: { | ||||||
|         return Decode(request); |         return Decode(request); | ||||||
|     } |     } | ||||||
|     case DecoderCommand::Unknown: { |     case DecoderCommand::Unknown: { | ||||||
|         BinaryResponse response; |         BinaryMessage response = request; | ||||||
|         std::memcpy(&response, &request, sizeof(response)); |         response.header.result = ResultStatus::Success; | ||||||
|         response.unknown1 = 0x0; |  | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
|     default: |     default: | ||||||
|         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast<u16>(request.cmd)); |         LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", | ||||||
|  |                   static_cast<u16>(request.header.cmd)); | ||||||
|         return std::nullopt; |         return std::nullopt; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& request) { | std::optional<BinaryMessage> WMFDecoder::Impl::Initalize(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response = request; | ||||||
|     std::memcpy(&response, &request, sizeof(response)); |     response.header.result = ResultStatus::Success; | ||||||
|     response.unknown1 = 0x0; |  | ||||||
| 
 | 
 | ||||||
|     format_selected = false; // select format again if application request initialize the DSP
 |     format_selected = false; // select format again if application request initialize the DSP
 | ||||||
|     return response; |     return response; | ||||||
|  | @ -186,13 +185,13 @@ MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, | ||||||
|     return MFOutputState::FatalError; |     return MFOutputState::FatalError; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& request) { | std::optional<BinaryMessage> WMFDecoder::Impl::Decode(const BinaryMessage& request) { | ||||||
|     BinaryResponse response; |     BinaryMessage response{}; | ||||||
|     response.codec = request.codec; |     response.header.codec = request.header.codec; | ||||||
|     response.cmd = request.cmd; |     response.header.cmd = request.header.cmd; | ||||||
|     response.size = request.size; |     response.decode_aac_response.size = request.decode_aac_request.size; | ||||||
|     response.num_channels = 2; |     response.decode_aac_response.num_channels = 2; | ||||||
|     response.num_samples = 1024; |     response.decode_aac_response.num_samples = 1024; | ||||||
| 
 | 
 | ||||||
|     if (!transform_initialized) { |     if (!transform_initialized) { | ||||||
|         LOG_DEBUG(Audio_DSP, "Decoder not initialized"); |         LOG_DEBUG(Audio_DSP, "Decoder not initialized"); | ||||||
|  | @ -200,26 +199,29 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (request.src_addr < Memory::FCRAM_PADDR || |     if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || | ||||||
|         request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |         request.decode_aac_request.src_addr + request.decode_aac_request.size > | ||||||
|         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); |             Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|  |         LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", | ||||||
|  |                   request.decode_aac_request.src_addr); | ||||||
|         return std::nullopt; |         return std::nullopt; | ||||||
|     } |     } | ||||||
|     u8* data = memory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); |     u8* data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR); | ||||||
| 
 | 
 | ||||||
|     std::array<std::vector<u8>, 2> out_streams; |     std::array<std::vector<u8>, 2> out_streams; | ||||||
|     unique_mfptr<IMFSample> sample; |     unique_mfptr<IMFSample> sample; | ||||||
|     MFInputState input_status = MFInputState::OK; |     MFInputState input_status = MFInputState::OK; | ||||||
|     MFOutputState output_status = MFOutputState::OK; |     MFOutputState output_status = MFOutputState::OK; | ||||||
|     std::optional<ADTSMeta> adts_meta = DetectMediaType((char*)data, request.size); |     std::optional<ADTSMeta> adts_meta = | ||||||
|  |         DetectMediaType((char*)data, request.decode_aac_request.size); | ||||||
| 
 | 
 | ||||||
|     if (!adts_meta) { |     if (!adts_meta) { | ||||||
|         LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream"); |         LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream"); | ||||||
|         return response; |         return response; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     response.sample_rate = GetSampleRateEnum(adts_meta->ADTSHeader.samplerate); |     response.decode_aac_response.sample_rate = GetSampleRateEnum(adts_meta->ADTSHeader.samplerate); | ||||||
|     response.num_channels = adts_meta->ADTSHeader.channels; |     response.decode_aac_response.num_channels = adts_meta->ADTSHeader.channels; | ||||||
| 
 | 
 | ||||||
|     if (!format_selected) { |     if (!format_selected) { | ||||||
|         LOG_DEBUG(Audio_DSP, "New ADTS stream: channels = {}, sample rate = {}", |         LOG_DEBUG(Audio_DSP, "New ADTS stream: channels = {}, sample rate = {}", | ||||||
|  | @ -234,7 +236,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
|         format_selected = true; |         format_selected = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     sample = CreateSample((void*)data, request.size, 1, 0); |     sample = CreateSample(data, request.decode_aac_request.size, 1, 0); | ||||||
|     sample->SetUINT32(MFSampleExtension_CleanPoint, 1); |     sample->SetUINT32(MFSampleExtension_CleanPoint, 1); | ||||||
| 
 | 
 | ||||||
|     while (true) { |     while (true) { | ||||||
|  | @ -263,24 +265,28 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Decode(const BinaryRequest& requ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (out_streams[0].size() != 0) { |     if (out_streams[0].size() != 0) { | ||||||
|         if (request.dst_addr_ch0 < Memory::FCRAM_PADDR || |         if (request.decode_aac_request.dst_addr_ch0 < Memory::FCRAM_PADDR || | ||||||
|             request.dst_addr_ch0 + out_streams[0].size() > |             request.decode_aac_request.dst_addr_ch0 + out_streams[0].size() > | ||||||
|                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", request.dst_addr_ch0); |             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", | ||||||
|  |                       request.decode_aac_request.dst_addr_ch0); | ||||||
|             return std::nullopt; |             return std::nullopt; | ||||||
|         } |         } | ||||||
|         std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch0 - Memory::FCRAM_PADDR), |         std::memcpy( | ||||||
|  |             memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch0 - Memory::FCRAM_PADDR), | ||||||
|             out_streams[0].data(), out_streams[0].size()); |             out_streams[0].data(), out_streams[0].size()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (out_streams[1].size() != 0) { |     if (out_streams[1].size() != 0) { | ||||||
|         if (request.dst_addr_ch1 < Memory::FCRAM_PADDR || |         if (request.decode_aac_request.dst_addr_ch1 < Memory::FCRAM_PADDR || | ||||||
|             request.dst_addr_ch1 + out_streams[1].size() > |             request.decode_aac_request.dst_addr_ch1 + out_streams[1].size() > | ||||||
|                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { |                 Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { | ||||||
|             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", request.dst_addr_ch1); |             LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", | ||||||
|  |                       request.decode_aac_request.dst_addr_ch1); | ||||||
|             return std::nullopt; |             return std::nullopt; | ||||||
|         } |         } | ||||||
|         std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), |         std::memcpy( | ||||||
|  |             memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch1 - Memory::FCRAM_PADDR), | ||||||
|             out_streams[1].data(), out_streams[1].size()); |             out_streams[1].data(), out_streams[1].size()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -291,7 +297,7 @@ WMFDecoder::WMFDecoder(Memory::MemorySystem& memory) : impl(std::make_unique<Imp | ||||||
| 
 | 
 | ||||||
| WMFDecoder::~WMFDecoder() = default; | WMFDecoder::~WMFDecoder() = default; | ||||||
| 
 | 
 | ||||||
| std::optional<BinaryResponse> WMFDecoder::ProcessRequest(const BinaryRequest& request) { | std::optional<BinaryMessage> WMFDecoder::ProcessRequest(const BinaryMessage& request) { | ||||||
|     return impl->ProcessRequest(request); |     return impl->ProcessRequest(request); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ class WMFDecoder final : public DecoderBase { | ||||||
| public: | public: | ||||||
|     explicit WMFDecoder(Memory::MemorySystem& memory); |     explicit WMFDecoder(Memory::MemorySystem& memory); | ||||||
|     ~WMFDecoder() override; |     ~WMFDecoder() override; | ||||||
|     std::optional<BinaryResponse> ProcessRequest(const BinaryRequest& request) override; |     std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) override; | ||||||
|     bool IsValid() const override; |     bool IsValid() const override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |  | ||||||
|  | @ -476,7 +476,7 @@ void DspLle::UnloadComponent() { | ||||||
|     impl->UnloadComponent(); |     impl->UnloadComponent(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DspLle::DspLle(Memory::MemorySystem& memory,Core::Timing& timing, bool multithread) | DspLle::DspLle(Memory::MemorySystem& memory, Core::Timing& timing, bool multithread) | ||||||
|     : impl(std::make_unique<Impl>(timing, multithread)) { |     : impl(std::make_unique<Impl>(timing, multithread)) { | ||||||
|     Teakra::AHBMCallback ahbm; |     Teakra::AHBMCallback ahbm; | ||||||
|     ahbm.read8 = [&memory](u32 address) -> u8 { |     ahbm.read8 = [&memory](u32 address) -> u8 { | ||||||
|  |  | ||||||
|  | @ -28,26 +28,26 @@ TEST_CASE("DSP HLE Audio Decoder", "[audio_core]") { | ||||||
| #elif HAVE_FFMPEG | #elif HAVE_FFMPEG | ||||||
|             std::make_unique<AudioCore::HLE::FFMPEGDecoder>(memory); |             std::make_unique<AudioCore::HLE::FFMPEGDecoder>(memory); | ||||||
| #endif | #endif | ||||||
|         AudioCore::HLE::BinaryRequest request; |         AudioCore::HLE::BinaryMessage request{}; | ||||||
| 
 | 
 | ||||||
|         request.codec = AudioCore::HLE::DecoderCodec::AAC; |         request.header.codec = AudioCore::HLE::DecoderCodec::DecodeAAC; | ||||||
|         request.cmd = AudioCore::HLE::DecoderCommand::Init; |         request.header.cmd = AudioCore::HLE::DecoderCommand::Init; | ||||||
|         // initialize decoder
 |         // initialize decoder
 | ||||||
|         std::optional<AudioCore::HLE::BinaryResponse> response = decoder->ProcessRequest(request); |         std::optional<AudioCore::HLE::BinaryMessage> response = decoder->ProcessRequest(request); | ||||||
| 
 | 
 | ||||||
|         request.cmd = AudioCore::HLE::DecoderCommand::Decode; |         request.header.cmd = AudioCore::HLE::DecoderCommand::EncodeDecode; | ||||||
|         u8* fcram = memory.GetFCRAMPointer(0); |         u8* fcram = memory.GetFCRAMPointer(0); | ||||||
| 
 | 
 | ||||||
|         memcpy(fcram, fixure_buffer, fixure_buffer_size); |         memcpy(fcram, fixure_buffer, fixure_buffer_size); | ||||||
|         request.src_addr = Memory::FCRAM_PADDR; |         request.decode_aac_request.src_addr = Memory::FCRAM_PADDR; | ||||||
|         request.dst_addr_ch0 = Memory::FCRAM_PADDR + 1024; |         request.decode_aac_request.dst_addr_ch0 = Memory::FCRAM_PADDR + 1024; | ||||||
|         request.dst_addr_ch1 = Memory::FCRAM_PADDR + 1048576; // 1 MB
 |         request.decode_aac_request.dst_addr_ch1 = Memory::FCRAM_PADDR + 1048576; // 1 MB
 | ||||||
|         request.size = fixure_buffer_size; |         request.decode_aac_request.size = fixure_buffer_size; | ||||||
| 
 | 
 | ||||||
|         response = decoder->ProcessRequest(request); |         response = decoder->ProcessRequest(request); | ||||||
|         response = decoder->ProcessRequest(request); |         response = decoder->ProcessRequest(request); | ||||||
|         // remove this line
 |         // remove this line
 | ||||||
|         request.src_addr = Memory::FCRAM_PADDR; |         request.decode_aac_request.src_addr = Memory::FCRAM_PADDR; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue