diff --git a/src/core/libraries/ajm/ajm.cpp b/src/core/libraries/ajm/ajm.cpp index 80681cbaf..2396669b6 100644 --- a/src/core/libraries/ajm/ajm.cpp +++ b/src/core/libraries/ajm/ajm.cpp @@ -13,8 +13,31 @@ namespace Libraries::Ajm { +constexpr int ORBIS_AJM_CHANNELMASK_MONO = 0x0004; +constexpr int ORBIS_AJM_CHANNELMASK_STEREO = 0x0003; +constexpr int ORBIS_AJM_CHANNELMASK_QUAD = 0x0033; +constexpr int ORBIS_AJM_CHANNELMASK_5POINT1 = 0x060F; +constexpr int ORBIS_AJM_CHANNELMASK_7POINT1 = 0x063F; + static std::unique_ptr context{}; +u32 GetChannelMask(u32 num_channels) { + switch (num_channels) { + case 1: + return ORBIS_AJM_CHANNELMASK_MONO; + case 2: + return ORBIS_AJM_CHANNELMASK_STEREO; + case 4: + return ORBIS_AJM_CHANNELMASK_QUAD; + case 6: + return ORBIS_AJM_CHANNELMASK_5POINT1; + case 8: + return ORBIS_AJM_CHANNELMASK_7POINT1; + default: + UNREACHABLE(); + } +} + int PS4_SYSV_ABI sceAjmBatchCancel(const u32 context_id, const u32 batch_id) { LOG_INFO(Lib_Ajm, "called context_id = {} batch_id = {}", context_id, batch_id); return context->BatchCancel(batch_id); diff --git a/src/core/libraries/ajm/ajm.h b/src/core/libraries/ajm/ajm.h index 4935b09b3..1ac7c7629 100644 --- a/src/core/libraries/ajm/ajm.h +++ b/src/core/libraries/ajm/ajm.h @@ -141,6 +141,8 @@ static_assert(sizeof(AjmInstanceFlags) == 8); struct AjmDecMp3ParseFrame; +u32 GetChannelMask(u32 num_channels); + int PS4_SYSV_ABI sceAjmBatchCancel(const u32 context_id, const u32 batch_id); int PS4_SYSV_ABI sceAjmBatchErrorDump(); void* PS4_SYSV_ABI sceAjmBatchJobControlBufferRa(void* p_buffer, u32 instance_id, u64 flags, diff --git a/src/core/libraries/ajm/ajm_at9.cpp b/src/core/libraries/ajm/ajm_at9.cpp index b945e3cdd..7fff0ff0c 100644 --- a/src/core/libraries/ajm/ajm_at9.cpp +++ b/src/core/libraries/ajm/ajm_at9.cpp @@ -129,4 +129,15 @@ std::tuple AjmAt9Decoder::ProcessData(std::span& in_buf, SparseOut return {1, samples_written / m_codec_info.channels}; } +AjmSidebandFormat AjmAt9Decoder::GetFormat() { + return AjmSidebandFormat{ + .num_channels = u32(m_codec_info.channels), + .channel_mask = GetChannelMask(u32(m_codec_info.channels)), + .sampl_freq = u32(m_codec_info.samplingRate), + .sample_encoding = m_format, + .bitrate = u32(m_codec_info.samplingRate * GetPointCodeSize() * 8), + .reserved = 0, + }; +} + } // namespace Libraries::Ajm diff --git a/src/core/libraries/ajm/ajm_at9.h b/src/core/libraries/ajm/ajm_at9.h index 0864bba14..e5f65db93 100644 --- a/src/core/libraries/ajm/ajm_at9.h +++ b/src/core/libraries/ajm/ajm_at9.h @@ -34,6 +34,7 @@ struct AjmAt9Decoder final : AjmCodec { void Reset() override; void Initialize(const void* buffer, u32 buffer_size) override; void GetInfo(void* out_info) override; + AjmSidebandFormat GetFormat() override; std::tuple ProcessData(std::span& input, SparseOutputBuffer& output, AjmSidebandGaplessDecode& gapless, std::optional max_samples) override; diff --git a/src/core/libraries/ajm/ajm_instance.cpp b/src/core/libraries/ajm/ajm_instance.cpp index dc4e631d9..85a6f54a1 100644 --- a/src/core/libraries/ajm/ajm_instance.cpp +++ b/src/core/libraries/ajm/ajm_instance.cpp @@ -102,6 +102,9 @@ void AjmInstance::ExecuteJob(AjmJob& job) { m_gapless.skipped_samples = 0; m_codec->Reset(); } + if (job.output.p_format != nullptr) { + *job.output.p_format = m_codec->GetFormat(); + } if (job.output.p_gapless_decode != nullptr) { *job.output.p_gapless_decode = m_gapless; } diff --git a/src/core/libraries/ajm/ajm_instance.h b/src/core/libraries/ajm/ajm_instance.h index 96a30ef47..d1d398ae8 100644 --- a/src/core/libraries/ajm/ajm_instance.h +++ b/src/core/libraries/ajm/ajm_instance.h @@ -60,6 +60,7 @@ public: virtual void Initialize(const void* buffer, u32 buffer_size) = 0; virtual void Reset() = 0; virtual void GetInfo(void* out_info) = 0; + virtual AjmSidebandFormat GetFormat() = 0; virtual std::tuple ProcessData(std::span& input, SparseOutputBuffer& output, AjmSidebandGaplessDecode& gapless, std::optional max_samples_per_channel) = 0; diff --git a/src/core/libraries/ajm/ajm_mp3.cpp b/src/core/libraries/ajm/ajm_mp3.cpp index d39b5bb88..eb65fe2a8 100644 --- a/src/core/libraries/ajm/ajm_mp3.cpp +++ b/src/core/libraries/ajm/ajm_mp3.cpp @@ -192,4 +192,9 @@ int AjmMp3Decoder::ParseMp3Header(const u8* buf, u32 stream_size, int parse_ofl, return ORBIS_OK; } +AjmSidebandFormat AjmMp3Decoder::GetFormat() { + LOG_ERROR(Lib_Ajm, "Unimplemented"); + return AjmSidebandFormat{}; +}; + } // namespace Libraries::Ajm diff --git a/src/core/libraries/ajm/ajm_mp3.h b/src/core/libraries/ajm/ajm_mp3.h index e6f4f7af6..0ae956d61 100644 --- a/src/core/libraries/ajm/ajm_mp3.h +++ b/src/core/libraries/ajm/ajm_mp3.h @@ -56,6 +56,7 @@ public: void Reset() override; void Initialize(const void* buffer, u32 buffer_size) override {} void GetInfo(void* out_info) override; + AjmSidebandFormat GetFormat() override; std::tuple ProcessData(std::span& input, SparseOutputBuffer& output, AjmSidebandGaplessDecode& gapless, std::optional max_samples_per_channel) override;