citra/src/audio_core/hle/decoder.h

150 lines
4.3 KiB
C++
Raw Normal View History

2018-12-09 22:25:45 +01:00
// Copyright 2018 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <optional>
#include <vector>
#include "common/common_types.h"
#include "common/swap.h"
#include "core/core.h"
namespace AudioCore::HLE {
enum class DecoderCommand : u16 {
Init = 0,
EncodeDecode = 1,
Unknown = 2, // Probably UnInit
2018-12-09 22:25:45 +01:00
};
enum class DecoderCodec : u16 {
None = 0,
DecodeAAC = 1,
EncodeAAC = 2,
};
enum class ResultStatus : u32 {
Success = 0,
Error = 1,
2018-12-09 22:25:45 +01:00
};
enum class DecoderSampleRate : u32 {
Rate48000 = 0,
Rate44100 = 1,
Rate32000 = 2,
Rate24000 = 3,
Rate22050 = 4,
Rate16000 = 5,
Rate12000 = 6,
Rate11025 = 7,
Rate8000 = 8
};
// 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 {
2018-12-09 22:25:45 +01:00
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; // unused?
u32_le unknown2 = 0; // unused?
2018-12-09 22:25:45 +01:00
};
struct DecodeAACResponse {
enum_le<DecoderSampleRate> sample_rate;
2018-12-09 22:25:45 +01:00
u32_le num_channels = 0; // this is a guess, so far I only observed 2 here
u32_le size = 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
};
// 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;
2018-12-09 22:25:45 +01:00
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;
};
2018-12-09 22:25:45 +01:00
};
static_assert(sizeof(BinaryMessage) == 32, "Unexpected struct size for BinaryMessage");
2018-12-09 22:25:45 +01:00
enum_le<DecoderSampleRate> GetSampleRateEnum(u32 sample_rate);
2018-12-09 22:25:45 +01:00
class DecoderBase {
public:
2018-12-16 15:03:23 +01:00
virtual ~DecoderBase();
virtual std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) = 0;
2019-12-08 22:19:19 +01:00
/// Return true if this Decoder can be loaded. Return false if the system cannot create the
/// decoder
virtual bool IsValid() const = 0;
2018-12-09 22:25:45 +01:00
};
class NullDecoder final : public DecoderBase {
public:
NullDecoder();
~NullDecoder() override;
std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request) override;
2019-12-08 22:19:19 +01:00
bool IsValid() const override {
return true;
}
2018-12-09 22:25:45 +01:00
};
} // namespace AudioCore::HLE