diff --git a/src/audio_core/hle/audiotoolbox_decoder.cpp b/src/audio_core/hle/audiotoolbox_decoder.cpp index c3e5ebf78..2b122f008 100644 --- a/src/audio_core/hle/audiotoolbox_decoder.cpp +++ b/src/audio_core/hle/audiotoolbox_decoder.cpp @@ -17,11 +17,11 @@ class AudioToolboxDecoder::Impl { public: explicit Impl(Memory::MemorySystem& memory); ~Impl(); - std::optional ProcessRequest(const BinaryRequest& request); + std::optional ProcessRequest(const BinaryMessage& request); private: - std::optional Initalize(const BinaryRequest& request); - std::optional Decode(const BinaryRequest& request); + std::optional Initalize(const BinaryMessage& request); + std::optional Decode(const BinaryMessage& request); void Clear(); bool InitializeDecoder(ADTSData& adts_header); @@ -43,12 +43,11 @@ private: AudioStreamPacketDescription packet_description; }; -AudioToolboxDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) {} +AudioToolboxDecoder::Impl::Impl(Memory::MemorySystem& memory_) : memory(memory_) {} -std::optional AudioToolboxDecoder::Impl::Initalize(const BinaryRequest& request) { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; +std::optional AudioToolboxDecoder::Impl::Initalize(const BinaryMessage& request) { + BinaryMessage response = request; + response.header.result = ResultStatus::Success; Clear(); return response; @@ -71,29 +70,29 @@ void AudioToolboxDecoder::Impl::Clear() { } } -std::optional AudioToolboxDecoder::Impl::ProcessRequest( - const BinaryRequest& request) { - if (request.codec != DecoderCodec::AAC) { +std::optional AudioToolboxDecoder::Impl::ProcessRequest( + const BinaryMessage& request) { + if (request.header.codec != DecoderCodec::DecodeAAC) { LOG_ERROR(Audio_DSP, "AudioToolbox AAC Decoder cannot handle such codec: {}", - static_cast(request.codec)); + static_cast(request.header.codec)); return {}; } - switch (request.cmd) { + switch (request.header.cmd) { case DecoderCommand::Init: { return Initalize(request); } - case DecoderCommand::Decode: { + case DecoderCommand::EncodeDecode: { return Decode(request); } case DecoderCommand::Unknown: { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; + BinaryMessage response = request; + response.header.result = ResultStatus::Success; return response; } default: - LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast(request.cmd)); + LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", + static_cast(request.header.cmd)); return {}; } } @@ -166,22 +165,24 @@ OSStatus AudioToolboxDecoder::Impl::DataFunc( return noErr; } -std::optional AudioToolboxDecoder::Impl::Decode(const BinaryRequest& request) { - BinaryResponse response; - response.codec = request.codec; - response.cmd = request.cmd; - response.size = request.size; +std::optional AudioToolboxDecoder::Impl::Decode(const BinaryMessage& request) { + BinaryMessage response{}; + response.header.codec = request.header.codec; + response.header.cmd = request.header.cmd; + response.decode_aac_response.size = request.decode_aac_request.size; - if (request.src_addr < Memory::FCRAM_PADDR || - request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { - LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); + if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || + request.decode_aac_request.src_addr + request.decode_aac_request.size > + Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { + LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", + request.decode_aac_request.src_addr); 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(data)); 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)) { return std::nullopt; @@ -218,15 +219,17 @@ std::optional AudioToolboxDecoder::Impl::Decode(const BinaryRequ curr_data = nullptr; curr_data_len = 0; - response.sample_rate = GetSampleRateEnum(static_cast(output_format.mSampleRate)); - response.num_channels = output_format.mChannelsPerFrame; - response.num_samples = num_frames; + response.decode_aac_response.sample_rate = + GetSampleRateEnum(static_cast(output_format.mSampleRate)); + 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 for (std::size_t ch = 0; ch < out_streams.size(); ch++) { if (!out_streams[ch].empty()) { 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 || dst + byte_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { 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; -std::optional AudioToolboxDecoder::ProcessRequest(const BinaryRequest& request) { +std::optional AudioToolboxDecoder::ProcessRequest(const BinaryMessage& request) { return impl->ProcessRequest(request); } diff --git a/src/audio_core/hle/audiotoolbox_decoder.h b/src/audio_core/hle/audiotoolbox_decoder.h index 10337691e..dcfe486d1 100644 --- a/src/audio_core/hle/audiotoolbox_decoder.h +++ b/src/audio_core/hle/audiotoolbox_decoder.h @@ -12,7 +12,7 @@ class AudioToolboxDecoder final : public DecoderBase { public: explicit AudioToolboxDecoder(Memory::MemorySystem& memory); ~AudioToolboxDecoder() override; - std::optional ProcessRequest(const BinaryRequest& request) override; + std::optional ProcessRequest(const BinaryMessage& request) override; bool IsValid() const override; private: diff --git a/src/audio_core/hle/decoder.cpp b/src/audio_core/hle/decoder.cpp index a4d4be181..a11fc4834 100644 --- a/src/audio_core/hle/decoder.cpp +++ b/src/audio_core/hle/decoder.cpp @@ -38,23 +38,25 @@ NullDecoder::NullDecoder() = default; NullDecoder::~NullDecoder() = default; -std::optional NullDecoder::ProcessRequest(const BinaryRequest& request) { - BinaryResponse response; - switch (request.cmd) { +std::optional NullDecoder::ProcessRequest(const BinaryMessage& request) { + BinaryMessage response{}; + switch (request.header.cmd) { case DecoderCommand::Init: case DecoderCommand::Unknown: - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; + response = request; + response.header.result = ResultStatus::Success; return response; - case DecoderCommand::Decode: - response.codec = request.codec; - response.cmd = DecoderCommand::Decode; - response.num_channels = 2; // Just assume stereo here - response.size = request.size; - response.num_samples = 1024; // Just assume 1024 here + case DecoderCommand::EncodeDecode: + response.header.codec = request.header.codec; + response.header.cmd = request.header.cmd; + response.header.result = ResultStatus::Success; + response.decode_aac_response.num_channels = 2; // Just assume stereo here + response.decode_aac_response.size = request.decode_aac_request.size; + response.decode_aac_response.num_samples = 1024; // Just assume 1024 here return response; default: - LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast(request.cmd)); + LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", + static_cast(request.header.cmd)); return std::nullopt; } }; diff --git a/src/audio_core/hle/decoder.h b/src/audio_core/hle/decoder.h index f713bb895..6c938a9fc 100644 --- a/src/audio_core/hle/decoder.h +++ b/src/audio_core/hle/decoder.h @@ -14,18 +14,22 @@ namespace AudioCore::HLE { enum class DecoderCommand : u16 { - Init, - Decode, - Unknown, + Init = 0, + EncodeDecode = 1, + Unknown = 2, // Probably UnInit }; enum class DecoderCodec : u16 { - None, - AAC, + None = 0, + 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 { Rate48000 = 0, Rate44100 = 1, @@ -38,40 +42,96 @@ enum class DecoderSampleRate : u32 { Rate8000 = 8 }; -struct BinaryRequest { - enum_le codec = - DecoderCodec::None; // this is a guess. until now only 0x1 was observed here - enum_le cmd = DecoderCommand::Init; - u32_le fixed = 0; +// The DSP replies with the same contents as the response too. +struct DecodeAACInitRequest { + u32_le unknown1 = 0; // observed 1 here + u32_le unknown2 = 0; // observed -1 here + 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 size = 0; u32_le dst_addr_ch0 = 0; u32_le dst_addr_ch1 = 0; - u32_le unknown1 = 0; - u32_le unknown2 = 0; + u32_le unknown1 = 0; // unused? + u32_le unknown2 = 0; // unused? }; -static_assert(sizeof(BinaryRequest) == 32, "Unexpected struct size for BinaryRequest"); -struct BinaryResponse { - enum_le codec = - DecoderCodec::None; // this could be something else. until now only 0x1 was observed here - enum_le cmd = DecoderCommand::Init; - u32_le unknown1 = 0; +struct DecodeAACResponse { enum_le sample_rate; u32_le num_channels = 0; // this is a guess, so far I only observed 2 here u32_le size = 0; - u32_le unknown3 = 0; - u32_le unknown4 = 0; + u32_le unknown1 = 0; + u32_le unknown2 = 0; 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 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 codec = + DecoderCodec::None; // this is a guess. until now only 0x1 was observed here + enum_le 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 result = ResultStatus::Error; + } header; + union { + std::array 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 GetSampleRateEnum(u32 sample_rate); class DecoderBase { public: virtual ~DecoderBase(); - virtual std::optional ProcessRequest(const BinaryRequest& request) = 0; + virtual std::optional ProcessRequest(const BinaryMessage& request) = 0; /// Return true if this Decoder can be loaded. Return false if the system cannot create the /// decoder virtual bool IsValid() const = 0; @@ -81,7 +141,7 @@ class NullDecoder final : public DecoderBase { public: NullDecoder(); ~NullDecoder() override; - std::optional ProcessRequest(const BinaryRequest& request) override; + std::optional ProcessRequest(const BinaryMessage& request) override; bool IsValid() const override { return true; } diff --git a/src/audio_core/hle/fdk_decoder.cpp b/src/audio_core/hle/fdk_decoder.cpp index 64459ac50..175db9b05 100644 --- a/src/audio_core/hle/fdk_decoder.cpp +++ b/src/audio_core/hle/fdk_decoder.cpp @@ -11,15 +11,15 @@ class FDKDecoder::Impl { public: explicit Impl(Memory::MemorySystem& memory); ~Impl(); - std::optional ProcessRequest(const BinaryRequest& request); + std::optional ProcessRequest(const BinaryMessage& request); bool IsValid() const { return decoder != nullptr; } private: - std::optional Initalize(const BinaryRequest& request); + std::optional Initalize(const BinaryMessage& request); - std::optional Decode(const BinaryRequest& request); + std::optional Decode(const BinaryMessage& request); void Clear(); @@ -58,10 +58,9 @@ FDKDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { } } -std::optional FDKDecoder::Impl::Initalize(const BinaryRequest& request) { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; +std::optional FDKDecoder::Impl::Initalize(const BinaryMessage& request) { + BinaryMessage response = request; + response.header.result = ResultStatus::Success; if (decoder) { LOG_INFO(Audio_DSP, "FDK Decoder initialized"); @@ -90,56 +89,58 @@ void FDKDecoder::Impl::Clear() { AACDEC_FLUSH & AACDEC_INTR & AACDEC_CONCEAL); } -std::optional FDKDecoder::Impl::ProcessRequest(const BinaryRequest& request) { - if (request.codec != DecoderCodec::AAC) { +std::optional FDKDecoder::Impl::ProcessRequest(const BinaryMessage& request) { + if (request.header.codec != DecoderCodec::DecodeAAC) { LOG_ERROR(Audio_DSP, "FDK AAC Decoder cannot handle such codec: {}", - static_cast(request.codec)); + static_cast(request.header.codec)); return {}; } - switch (request.cmd) { + switch (request.header.cmd) { case DecoderCommand::Init: { return Initalize(request); } - case DecoderCommand::Decode: { + case DecoderCommand::EncodeDecode: { return Decode(request); } case DecoderCommand::Unknown: { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; + BinaryMessage response = request; + response.header.result = 0x0; return response; } default: - LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast(request.cmd)); + LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", + static_cast(request.header.cmd)); return {}; } } -std::optional FDKDecoder::Impl::Decode(const BinaryRequest& request) { - BinaryResponse response; - response.codec = request.codec; - response.cmd = request.cmd; - response.size = request.size; +std::optional FDKDecoder::Impl::Decode(const BinaryMessage& request) { + BinaryMessages response; + response.header.codec = request.header.codec; + response.header.cmd = request.header.cmd; + response.decode_aac_response.size = request.decode_aac_request.size; if (!decoder) { LOG_DEBUG(Audio_DSP, "Decoder not initalized"); // This is a hack to continue games that are not compiled with the aac codec - response.num_channels = 2; - response.num_samples = 1024; + response.decode_aac_response.num_channels = 2; + response.decode_aac_response.num_samples = 1024; return response; } - if (request.src_addr < Memory::FCRAM_PADDR || - request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { - LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); + if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || + request.decode_aac_request.src_addr + request.size > + Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { + LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", + request.decode_aac_request.src_addr); return {}; } u8* data = memory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); std::array, 2> out_streams; - std::size_t data_size = request.size; + std::size_t data_size = request.decode_aac_request.size; // decoding loops AAC_DECODER_ERROR result = AAC_DEC_OK; @@ -168,9 +169,9 @@ std::optional FDKDecoder::Impl::Decode(const BinaryRequest& requ // get the stream information stream_info = aacDecoder_GetStreamInfo(decoder); // fill the stream information for binary response - response.sample_rate = GetSampleRateEnum(stream_info->sampleRate); - response.num_channels = stream_info->numChannels; - response.num_samples = stream_info->frameSize; + response.decode_aac_response.sample_rate = GetSampleRateEnum(stream_info->sampleRate); + response.decode_aac_response.num_channels = stream_info->numChannels; + response.decode_aac_response.num_samples = stream_info->frameSize; // fill the output // the sample size = frame_size * channel_counts for (int sample = 0; sample < stream_info->frameSize; sample++) { @@ -193,7 +194,8 @@ std::optional FDKDecoder::Impl::Decode(const BinaryRequest& requ for (std::size_t ch = 0; ch < out_streams.size(); ch++) { if (!out_streams[ch].empty()) { 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 || dst + byte_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { 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 FDKDecoder::ProcessRequest(const BinaryRequest& request) { +std::optional FDKDecoder::ProcessRequest(const BinaryMessage& request) { return impl->ProcessRequest(request); } diff --git a/src/audio_core/hle/fdk_decoder.h b/src/audio_core/hle/fdk_decoder.h index 337c6054a..65d6e8cd3 100644 --- a/src/audio_core/hle/fdk_decoder.h +++ b/src/audio_core/hle/fdk_decoder.h @@ -12,7 +12,7 @@ class FDKDecoder final : public DecoderBase { public: explicit FDKDecoder(Memory::MemorySystem& memory); ~FDKDecoder() override; - std::optional ProcessRequest(const BinaryRequest& request) override; + std::optional ProcessRequest(const BinaryMessage& request) override; bool IsValid() const override; private: diff --git a/src/audio_core/hle/ffmpeg_decoder.cpp b/src/audio_core/hle/ffmpeg_decoder.cpp index c9d7abe3f..8f9382c10 100644 --- a/src/audio_core/hle/ffmpeg_decoder.cpp +++ b/src/audio_core/hle/ffmpeg_decoder.cpp @@ -11,17 +11,17 @@ class FFMPEGDecoder::Impl { public: explicit Impl(Memory::MemorySystem& memory); ~Impl(); - std::optional ProcessRequest(const BinaryRequest& request); + std::optional ProcessRequest(const BinaryMessage& request); bool IsValid() const { return have_ffmpeg_dl; } private: - std::optional Initalize(const BinaryRequest& request); + std::optional Initalize(const BinaryMessage& request); void Clear(); - std::optional Decode(const BinaryRequest& request); + std::optional Decode(const BinaryMessage& request); struct AVPacketDeleter { void operator()(AVPacket* packet) const { @@ -65,9 +65,9 @@ FFMPEGDecoder::Impl::Impl(Memory::MemorySystem& memory) : memory(memory) { FFMPEGDecoder::Impl::~Impl() = default; -std::optional FFMPEGDecoder::Impl::ProcessRequest(const BinaryRequest& request) { - if (request.codec != DecoderCodec::AAC) { - LOG_ERROR(Audio_DSP, "Got wrong codec {}", static_cast(request.codec)); +std::optional FFMPEGDecoder::Impl::ProcessRequest(const BinaryMessage& request) { + if (request.codec != DecoderCodec::DecodeAAC) { + LOG_ERROR(Audio_DSP, "Got wrong codec {}", static_cast(request.header.codec)); return {}; } @@ -79,25 +79,24 @@ std::optional FFMPEGDecoder::Impl::ProcessRequest(const BinaryRe return Decode(request); } case DecoderCommand::Unknown: { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; + BinaryMessage response = request; + response.header.result = ResultStatus::Success; return response; } default: - LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast(request.cmd)); + LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", + static_cast(request.header.cmd)); return {}; } } -std::optional FFMPEGDecoder::Impl::Initalize(const BinaryRequest& request) { +std::optional FFMPEGDecoder::Impl::Initalize(const BinaryMessage& request) { if (initalized) { Clear(); } - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; + BinaryMessage response = request; + response.header.result = ResultStatus::Success; if (!have_ffmpeg_dl) { return response; @@ -143,30 +142,32 @@ void FFMPEGDecoder::Impl::Clear() { av_packet.reset(); } -std::optional FFMPEGDecoder::Impl::Decode(const BinaryRequest& request) { - BinaryResponse response; - response.codec = request.codec; - response.cmd = request.cmd; - response.size = request.size; +std::optional FFMPEGDecoder::Impl::Decode(const BinaryMessage& request) { + BinaryMessage response; + response.header.codec = request.header.codec; + response.header.cmd = request.header.cmd; + response.decode_aac_response.size = request.decode_aac_request.size; if (!initalized) { LOG_DEBUG(Audio_DSP, "Decoder not initalized"); // This is a hack to continue games that are not compiled with the aac codec - response.num_channels = 2; - response.num_samples = 1024; + response.decode_aac_response.num_channels = 2; + response.decode_aac_response.num_samples = 1024; return response; } - if (request.src_addr < Memory::FCRAM_PADDR || - request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { - LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); + if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || + request.decode_aac_request.src_addr + request.decode_aac_request.size > + Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { + LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", + request.decode_aac_request.src_addr); return {}; } u8* data = memory.GetFCRAMPointer(request.src_addr - Memory::FCRAM_PADDR); std::array, 2> out_streams; - std::size_t data_size = request.size; + std::size_t data_size = request.decode_aac_request.size; while (data_size > 0) { if (!decoded_frame) { decoded_frame.reset(av_frame_alloc_dl()); @@ -211,9 +212,10 @@ std::optional FFMPEGDecoder::Impl::Decode(const BinaryRequest& r std::size_t size = bytes_per_sample * (decoded_frame->nb_samples); - response.sample_rate = GetSampleRateEnum(decoded_frame->sample_rate); - response.num_channels = decoded_frame->channels; - response.num_samples += decoded_frame->nb_samples; + response.decode_aac_response.sample_rate = + GetSampleRateEnum(decoded_frame->sample_rate); + 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 // convert it @@ -234,25 +236,29 @@ std::optional FFMPEGDecoder::Impl::Decode(const BinaryRequest& r } if (out_streams[0].size() != 0) { - if (request.dst_addr_ch0 < Memory::FCRAM_PADDR || - request.dst_addr_ch0 + out_streams[0].size() > + if (request.decode_aac_request.dst_addr_ch0 < Memory::FCRAM_PADDR || + request.decode_aac_request.dst_addr_ch0 + out_streams[0].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::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch0 - Memory::FCRAM_PADDR), - out_streams[0].data(), out_streams[0].size()); + std::memcpy( + memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch0 - Memory::FCRAM_PADDR), + out_streams[0].data(), out_streams[0].size()); } if (out_streams[1].size() != 0) { - if (request.dst_addr_ch1 < Memory::FCRAM_PADDR || - request.dst_addr_ch1 + out_streams[1].size() > + if (request.decode_aac_request.dst_addr_ch1 < Memory::FCRAM_PADDR || + request.decode_aac_request.dst_addr_ch1 + out_streams[1].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::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), - out_streams[1].data(), out_streams[1].size()); + std::memcpy( + memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch1 - Memory::FCRAM_PADDR), + out_streams[1].data(), out_streams[1].size()); } return response; } @@ -261,7 +267,7 @@ FFMPEGDecoder::FFMPEGDecoder(Memory::MemorySystem& memory) : impl(std::make_uniq FFMPEGDecoder::~FFMPEGDecoder() = default; -std::optional FFMPEGDecoder::ProcessRequest(const BinaryRequest& request) { +std::optional FFMPEGDecoder::ProcessRequest(const BinaryMessage& request) { return impl->ProcessRequest(request); } diff --git a/src/audio_core/hle/ffmpeg_decoder.h b/src/audio_core/hle/ffmpeg_decoder.h index ee5e8cda7..6c356776a 100644 --- a/src/audio_core/hle/ffmpeg_decoder.h +++ b/src/audio_core/hle/ffmpeg_decoder.h @@ -12,7 +12,7 @@ class FFMPEGDecoder final : public DecoderBase { public: explicit FFMPEGDecoder(Memory::MemorySystem& memory); ~FFMPEGDecoder() override; - std::optional ProcessRequest(const BinaryRequest& request) override; + std::optional ProcessRequest(const BinaryMessage& request) override; bool IsValid() const override; private: diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index d1514e30b..d7e70f328 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -40,7 +40,8 @@ using Service::DSP::DSP_DSP; 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 void DspHle::serialize(Archive& ar, const unsigned int) { @@ -291,21 +292,21 @@ void DspHle::Impl::PipeWrite(DspPipe pipe_number, const std::vector& buffer) } case DspPipe::Binary: { // TODO(B3N30): Make this async, and signal the interrupt - HLE::BinaryRequest request; + HLE::BinaryMessage request{}; if (sizeof(request) != buffer.size()) { LOG_CRITICAL(Audio_DSP, "got binary pipe with wrong size {}", buffer.size()); UNIMPLEMENTED(); return; } std::memcpy(&request, buffer.data(), buffer.size()); - if (request.codec != HLE::DecoderCodec::AAC) { - LOG_CRITICAL(Audio_DSP, "got unknown codec {}", static_cast(request.codec)); + if (request.header.codec != HLE::DecoderCodec::DecodeAAC) { + LOG_CRITICAL(Audio_DSP, "got unknown codec {}", static_cast(request.header.codec)); UNIMPLEMENTED(); return; } - std::optional response = decoder->ProcessRequest(request); + std::optional response = decoder->ProcessRequest(request); if (response) { - const HLE::BinaryResponse& value = *response; + const HLE::BinaryMessage& value = *response; pipe_data[static_cast(pipe_number)].resize(sizeof(value)); std::memcpy(pipe_data[static_cast(pipe_number)].data(), &value, sizeof(value)); } diff --git a/src/audio_core/hle/mediandk_decoder.cpp b/src/audio_core/hle/mediandk_decoder.cpp index f78db8e89..4dc3154dc 100644 --- a/src/audio_core/hle/mediandk_decoder.cpp +++ b/src/audio_core/hle/mediandk_decoder.cpp @@ -25,16 +25,16 @@ class MediaNDKDecoder::Impl { public: explicit Impl(Memory::MemorySystem& memory); ~Impl(); - std::optional ProcessRequest(const BinaryRequest& request); + std::optional ProcessRequest(const BinaryMessage& request); bool SetMediaType(const ADTSData& adts_data); private: - std::optional Initalize(const BinaryRequest& request); - std::optional Decode(const BinaryRequest& request); + std::optional Initalize(const BinaryMessage& request); + std::optional Decode(const BinaryMessage& request); - Memory::MemorySystem& mMemory; - std::unique_ptr mDecoder; + Memory::MemorySystem& memory; + std::unique_ptr decoder; // default: 2 channles, 48000 samplerate ADTSData mADTSData{ /*header_length*/ 7, /*MPEG2*/ false, /*profile*/ 2, @@ -42,28 +42,27 @@ private: /*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); } MediaNDKDecoder::Impl::~Impl() = default; -std::optional MediaNDKDecoder::Impl::Initalize(const BinaryRequest& request) { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; +std::optional MediaNDKDecoder::Impl::Initalize(const BinaryMessage& request) { + BinaryMessage response = request; + response.header.result = ResultStatus::Success; return response; } bool MediaNDKDecoder::Impl::SetMediaType(const ADTSData& adts_data) { 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.samplerate_idx == adts_data.samplerate_idx) { return true; } - mDecoder.reset(AMediaCodec_createDecoderByType(mime)); - if (mDecoder == nullptr) { + decoder.reset(AMediaCodec_createDecoderByType(mime)); + if (decoder == nullptr) { return false; } @@ -78,17 +77,17 @@ bool MediaNDKDecoder::Impl::SetMediaType(const ADTSData& adts_data) { AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_IS_ADTS, 1); 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) { AMediaFormat_delete(format); - mDecoder.reset(); + decoder.reset(); return false; } - status = AMediaCodec_start(mDecoder.get()); + status = AMediaCodec_start(decoder.get()); if (status != AMEDIA_OK) { AMediaFormat_delete(format); - mDecoder.reset(); + decoder.reset(); return false; } @@ -97,51 +96,53 @@ bool MediaNDKDecoder::Impl::SetMediaType(const ADTSData& adts_data) { return true; } -std::optional MediaNDKDecoder::Impl::ProcessRequest(const BinaryRequest& request) { - if (request.codec != DecoderCodec::AAC) { +std::optional MediaNDKDecoder::Impl::ProcessRequest(const BinaryMessage& request) { + if (request.header.codec != DecoderCodec::DecodeAAC) { LOG_ERROR(Audio_DSP, "AAC Decoder cannot handle such codec: {}", - static_cast(request.codec)); + static_cast(request.header.codec)); return {}; } - switch (request.cmd) { + switch (request.header.cmd) { case DecoderCommand::Init: { return Initalize(request); } - case DecoderCommand::Decode: { + case DecoderCommand::EncodeDecode: { return Decode(request); } case DecoderCommand::Unknown: { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; + BinaryMessage response = request; + response.header.result = ResultStatus::Success; return response; } default: - LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast(request.cmd)); + LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", + static_cast(request.header.cmd)); return {}; } } -std::optional MediaNDKDecoder::Impl::Decode(const BinaryRequest& request) { - BinaryResponse response; - response.codec = request.codec; - response.cmd = request.cmd; - response.size = request.size; - response.num_samples = 1024; +std::optional MediaNDKDecoder::Impl::Decode(const BinaryMessage& request) { + BinaryMessage response{}; + response.header.codec = request.header.codec; + response.header.cmd = request.header.cmd; + response.decode_aac_response.size = request.decode_aac_request.size; + response.decode_aac_response.num_samples = 1024; - if (request.src_addr < Memory::FCRAM_PADDR || - request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { - LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); + if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || + request.decode_aac_request.src_addr + request.decode_aac_request.size > + Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { + LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", + request.decode_aac_request.src_addr); 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(data)); SetMediaType(adts_data); - response.sample_rate = GetSampleRateEnum(adts_data.samplerate); - response.num_channels = adts_data.channels; - if (!mDecoder) { + response.decode_aac_response.sample_rate = GetSampleRateEnum(adts_data.samplerate); + response.decode_aac_response.num_channels = adts_data.channels; + if (!decoder) { LOG_ERROR(Audio_DSP, "Missing decoder for profile: {}, channels: {}, samplerate: {}", adts_data.profile, adts_data.channels, adts_data.samplerate); return {}; @@ -151,18 +152,18 @@ std::optional MediaNDKDecoder::Impl::Decode(const BinaryRequest& constexpr int timeout = 160; std::size_t buffer_size = 0; 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) { LOG_ERROR(Audio_DSP, "Failed to enqueue the input samples: {}", buffer_index); return response; } - buffer = AMediaCodec_getInputBuffer(mDecoder.get(), buffer_index, &buffer_size); - if (buffer_size < request.size) { + buffer = AMediaCodec_getInputBuffer(decoder.get(), buffer_index, &buffer_size); + if (buffer_size < request.decode_aac_request.size) { return response; } - std::memcpy(buffer, data, request.size); - media_status_t status = - AMediaCodec_queueInputBuffer(mDecoder.get(), buffer_index, 0, request.size, 0, 0); + std::memcpy(buffer, data, request.decode_aac_request.size); + media_status_t status = AMediaCodec_queueInputBuffer(decoder.get(), buffer_index, 0, + request.decode_aac_request.size, 0, 0); if (status != AMEDIA_OK) { LOG_WARNING(Audio_DSP, "Try queue input buffer again later!"); return response; @@ -171,7 +172,7 @@ std::optional MediaNDKDecoder::Impl::Decode(const BinaryRequest& // output AMediaCodecBufferInfo info; std::array, 2> out_streams; - buffer_index = AMediaCodec_dequeueOutputBuffer(mDecoder.get(), &info, timeout); + buffer_index = AMediaCodec_dequeueOutputBuffer(decoder.get(), &info, timeout); switch (buffer_index) { case AMEDIACODEC_INFO_TRY_AGAIN_LATER: LOG_WARNING(Audio_DSP, "Failed to dequeue output buffer: timeout!"); @@ -180,47 +181,53 @@ std::optional MediaNDKDecoder::Impl::Decode(const BinaryRequest& LOG_WARNING(Audio_DSP, "Failed to dequeue output buffer: buffers changed!"); break; 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)); AMediaFormat_delete(format); - buffer_index = AMediaCodec_dequeueOutputBuffer(mDecoder.get(), &info, timeout); + buffer_index = AMediaCodec_dequeueOutputBuffer(decoder.get(), &info, timeout); } default: { 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) { - for (int channel = 0; channel < response.num_channels; channel++) { + for (int channel = 0; channel < response.decode_aac_response.num_channels; channel++) { u16 pcm_data; std::memcpy(&pcm_data, buffer + offset, sizeof(pcm_data)); out_streams[channel].push_back(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 size_t stream0_size = out_streams[0].size() * sizeof(u16); if (stream0_size != 0) { - if (request.dst_addr_ch0 < Memory::FCRAM_PADDR || - request.dst_addr_ch0 + stream0_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { - LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch0 {:08x}", request.dst_addr_ch0); + if (request.decode_aac_request.dst_addr_ch0 < Memory::FCRAM_PADDR || + request.decode_aac_request.dst_addr_ch0 + stream0_size > + 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; } - std::memcpy(mMemory.GetFCRAMPointer(request.dst_addr_ch0 - Memory::FCRAM_PADDR), - out_streams[0].data(), stream0_size); + std::memcpy( + memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch0 - Memory::FCRAM_PADDR), + out_streams[0].data(), stream0_size); } size_t stream1_size = out_streams[1].size() * sizeof(u16); if (stream1_size != 0) { - if (request.dst_addr_ch1 < Memory::FCRAM_PADDR || - request.dst_addr_ch1 + stream1_size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { - LOG_ERROR(Audio_DSP, "Got out of bounds dst_addr_ch1 {:08x}", request.dst_addr_ch1); + if (request.decode_aac_request.dst_addr_ch1 < Memory::FCRAM_PADDR || + request.decode_aac_request.dst_addr_ch1 + stream1_size > + 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; } - std::memcpy(mMemory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), - out_streams[1].data(), stream1_size); + std::memcpy( + memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch1 - Memory::FCRAM_PADDR), + out_streams[1].data(), stream1_size); } return response; } @@ -230,7 +237,7 @@ MediaNDKDecoder::MediaNDKDecoder(Memory::MemorySystem& memory) MediaNDKDecoder::~MediaNDKDecoder() = default; -std::optional MediaNDKDecoder::ProcessRequest(const BinaryRequest& request) { +std::optional MediaNDKDecoder::ProcessRequest(const BinaryMessage& request) { return impl->ProcessRequest(request); } diff --git a/src/audio_core/hle/mediandk_decoder.h b/src/audio_core/hle/mediandk_decoder.h index 1de1e15f7..344c367a5 100644 --- a/src/audio_core/hle/mediandk_decoder.h +++ b/src/audio_core/hle/mediandk_decoder.h @@ -11,7 +11,7 @@ class MediaNDKDecoder final : public DecoderBase { public: explicit MediaNDKDecoder(Memory::MemorySystem& memory); ~MediaNDKDecoder() override; - std::optional ProcessRequest(const BinaryRequest& request) override; + std::optional ProcessRequest(const BinaryMessage& request) override; bool IsValid() const override; private: diff --git a/src/audio_core/hle/wmf_decoder.cpp b/src/audio_core/hle/wmf_decoder.cpp index d5ac13fc8..dca0428fe 100644 --- a/src/audio_core/hle/wmf_decoder.cpp +++ b/src/audio_core/hle/wmf_decoder.cpp @@ -13,15 +13,15 @@ class WMFDecoder::Impl { public: explicit Impl(Memory::MemorySystem& memory); ~Impl(); - std::optional ProcessRequest(const BinaryRequest& request); + std::optional ProcessRequest(const BinaryMessage& request); bool IsValid() const { return is_valid; } private: - std::optional Initalize(const BinaryRequest& request); + std::optional Initalize(const BinaryMessage& request); - std::optional Decode(const BinaryRequest& request); + std::optional Decode(const BinaryMessage& request); MFOutputState DecodingLoop(ADTSData adts_header, std::array, 2>& out_streams); @@ -101,36 +101,35 @@ WMFDecoder::Impl::~Impl() { } } -std::optional WMFDecoder::Impl::ProcessRequest(const BinaryRequest& request) { - if (request.codec != DecoderCodec::AAC) { - LOG_ERROR(Audio_DSP, "Got unknown codec {}", static_cast(request.codec)); +std::optional WMFDecoder::Impl::ProcessRequest(const BinaryMessage& request) { + if (request.header.codec != DecoderCodec::DecodeAAC) { + LOG_ERROR(Audio_DSP, "Got unknown codec {}", static_cast(request.header.codec)); return std::nullopt; } - switch (request.cmd) { + switch (request.header.cmd) { case DecoderCommand::Init: { LOG_INFO(Audio_DSP, "WMFDecoder initializing"); return Initalize(request); } - case DecoderCommand::Decode: { + case DecoderCommand::EncodeDecode: { return Decode(request); } case DecoderCommand::Unknown: { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; + BinaryMessage response = request; + response.header.result = ResultStatus::Success; return response; } default: - LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", static_cast(request.cmd)); + LOG_ERROR(Audio_DSP, "Got unknown binary request: {}", + static_cast(request.header.cmd)); return std::nullopt; } } -std::optional WMFDecoder::Impl::Initalize(const BinaryRequest& request) { - BinaryResponse response; - std::memcpy(&response, &request, sizeof(response)); - response.unknown1 = 0x0; +std::optional WMFDecoder::Impl::Initalize(const BinaryMessage& request) { + BinaryMessage response = request; + response.header.result = ResultStatus::Success; format_selected = false; // select format again if application request initialize the DSP return response; @@ -186,13 +185,13 @@ MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header, return MFOutputState::FatalError; } -std::optional WMFDecoder::Impl::Decode(const BinaryRequest& request) { - BinaryResponse response; - response.codec = request.codec; - response.cmd = request.cmd; - response.size = request.size; - response.num_channels = 2; - response.num_samples = 1024; +std::optional WMFDecoder::Impl::Decode(const BinaryMessage& request) { + BinaryMessage response{}; + response.header.codec = request.header.codec; + response.header.cmd = request.header.cmd; + response.decode_aac_response.size = request.decode_aac_request.size; + response.decode_aac_response.num_channels = 2; + response.decode_aac_response.num_samples = 1024; if (!transform_initialized) { LOG_DEBUG(Audio_DSP, "Decoder not initialized"); @@ -200,26 +199,29 @@ std::optional WMFDecoder::Impl::Decode(const BinaryRequest& requ return response; } - if (request.src_addr < Memory::FCRAM_PADDR || - request.src_addr + request.size > Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { - LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", request.src_addr); + if (request.decode_aac_request.src_addr < Memory::FCRAM_PADDR || + request.decode_aac_request.src_addr + request.decode_aac_request.size > + Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { + LOG_ERROR(Audio_DSP, "Got out of bounds src_addr {:08x}", + request.decode_aac_request.src_addr); 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, 2> out_streams; unique_mfptr sample; MFInputState input_status = MFInputState::OK; MFOutputState output_status = MFOutputState::OK; - std::optional adts_meta = DetectMediaType((char*)data, request.size); + std::optional adts_meta = + DetectMediaType((char*)data, request.decode_aac_request.size); if (!adts_meta) { LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream"); return response; } - response.sample_rate = GetSampleRateEnum(adts_meta->ADTSHeader.samplerate); - response.num_channels = adts_meta->ADTSHeader.channels; + response.decode_aac_response.sample_rate = GetSampleRateEnum(adts_meta->ADTSHeader.samplerate); + response.decode_aac_response.num_channels = adts_meta->ADTSHeader.channels; if (!format_selected) { LOG_DEBUG(Audio_DSP, "New ADTS stream: channels = {}, sample rate = {}", @@ -234,7 +236,7 @@ std::optional WMFDecoder::Impl::Decode(const BinaryRequest& requ 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); while (true) { @@ -263,25 +265,29 @@ std::optional WMFDecoder::Impl::Decode(const BinaryRequest& requ } if (out_streams[0].size() != 0) { - if (request.dst_addr_ch0 < Memory::FCRAM_PADDR || - request.dst_addr_ch0 + out_streams[0].size() > + if (request.decode_aac_request.dst_addr_ch0 < Memory::FCRAM_PADDR || + request.decode_aac_request.dst_addr_ch0 + out_streams[0].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; } - std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch0 - Memory::FCRAM_PADDR), - out_streams[0].data(), out_streams[0].size()); + std::memcpy( + memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch0 - Memory::FCRAM_PADDR), + out_streams[0].data(), out_streams[0].size()); } if (out_streams[1].size() != 0) { - if (request.dst_addr_ch1 < Memory::FCRAM_PADDR || - request.dst_addr_ch1 + out_streams[1].size() > + if (request.decode_aac_request.dst_addr_ch1 < Memory::FCRAM_PADDR || + request.decode_aac_request.dst_addr_ch1 + out_streams[1].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; } - std::memcpy(memory.GetFCRAMPointer(request.dst_addr_ch1 - Memory::FCRAM_PADDR), - out_streams[1].data(), out_streams[1].size()); + std::memcpy( + memory.GetFCRAMPointer(request.decode_aac_request.dst_addr_ch1 - Memory::FCRAM_PADDR), + out_streams[1].data(), out_streams[1].size()); } return response; @@ -291,7 +297,7 @@ WMFDecoder::WMFDecoder(Memory::MemorySystem& memory) : impl(std::make_unique WMFDecoder::ProcessRequest(const BinaryRequest& request) { +std::optional WMFDecoder::ProcessRequest(const BinaryMessage& request) { return impl->ProcessRequest(request); } diff --git a/src/audio_core/hle/wmf_decoder.h b/src/audio_core/hle/wmf_decoder.h index a089f2322..73b83acbf 100644 --- a/src/audio_core/hle/wmf_decoder.h +++ b/src/audio_core/hle/wmf_decoder.h @@ -12,7 +12,7 @@ class WMFDecoder final : public DecoderBase { public: explicit WMFDecoder(Memory::MemorySystem& memory); ~WMFDecoder() override; - std::optional ProcessRequest(const BinaryRequest& request) override; + std::optional ProcessRequest(const BinaryMessage& request) override; bool IsValid() const override; private: diff --git a/src/audio_core/lle/lle.cpp b/src/audio_core/lle/lle.cpp index 09202e489..5439841f2 100644 --- a/src/audio_core/lle/lle.cpp +++ b/src/audio_core/lle/lle.cpp @@ -476,7 +476,7 @@ void DspLle::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(timing, multithread)) { Teakra::AHBMCallback ahbm; ahbm.read8 = [&memory](u32 address) -> u8 { diff --git a/src/tests/audio_core/decoder_tests.cpp b/src/tests/audio_core/decoder_tests.cpp index a01c4a870..2409e298c 100644 --- a/src/tests/audio_core/decoder_tests.cpp +++ b/src/tests/audio_core/decoder_tests.cpp @@ -28,26 +28,26 @@ TEST_CASE("DSP HLE Audio Decoder", "[audio_core]") { #elif HAVE_FFMPEG std::make_unique(memory); #endif - AudioCore::HLE::BinaryRequest request; + AudioCore::HLE::BinaryMessage request{}; - request.codec = AudioCore::HLE::DecoderCodec::AAC; - request.cmd = AudioCore::HLE::DecoderCommand::Init; + request.header.codec = AudioCore::HLE::DecoderCodec::DecodeAAC; + request.header.cmd = AudioCore::HLE::DecoderCommand::Init; // initialize decoder - std::optional response = decoder->ProcessRequest(request); + std::optional response = decoder->ProcessRequest(request); - request.cmd = AudioCore::HLE::DecoderCommand::Decode; + request.header.cmd = AudioCore::HLE::DecoderCommand::EncodeDecode; u8* fcram = memory.GetFCRAMPointer(0); memcpy(fcram, fixure_buffer, fixure_buffer_size); - request.src_addr = Memory::FCRAM_PADDR; - request.dst_addr_ch0 = Memory::FCRAM_PADDR + 1024; - request.dst_addr_ch1 = Memory::FCRAM_PADDR + 1048576; // 1 MB - request.size = fixure_buffer_size; + request.decode_aac_request.src_addr = Memory::FCRAM_PADDR; + request.decode_aac_request.dst_addr_ch0 = Memory::FCRAM_PADDR + 1024; + request.decode_aac_request.dst_addr_ch1 = Memory::FCRAM_PADDR + 1048576; // 1 MB + request.decode_aac_request.size = fixure_buffer_size; response = decoder->ProcessRequest(request); response = decoder->ProcessRequest(request); // remove this line - request.src_addr = Memory::FCRAM_PADDR; + request.decode_aac_request.src_addr = Memory::FCRAM_PADDR; } }