* ajm: Initial ajm implementation

* AJM code improvements (#1453)

* Fix sideband buffer order (#1454)

* ajm: Attempt to add gapless support

* ajm_at9: Return superframes decoded in a single job

* WIP (#1460)

* Fix gapless decode and combine split buffers

* Fixed linux build

* fix number of samples reported with gapless decoding

* fixed number of remaining samples calculation

should fix the small crackling sounds that play every now and again

* refactor half ajm

* refactored most of ajm

* refactored ajm

* clang-format, in-repo libatrac9, removed debug stuff

---------

Co-authored-by: auser1337 <aaravsandhu10@outlook.com>
Co-authored-by: Vladislav Mikhalin <mikhalinvlad@gmail.com>
Co-authored-by: IndecisiveTurtle <geoster3d@gmail.com>
This commit is contained in:
georgemoralis 2024-11-05 09:16:57 +02:00 committed by GitHub
parent 76f440889b
commit f068f13e4a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 1678 additions and 58 deletions

View file

@ -3,6 +3,8 @@
#pragma once
#include "common/bit_field.h"
#include "common/enum.h"
#include "common/types.h"
namespace Core::Loader {
@ -11,28 +13,173 @@ class SymbolsResolver;
namespace Libraries::Ajm {
int PS4_SYSV_ABI sceAjmBatchCancel();
constexpr u32 ORBIS_AT9_CONFIG_DATA_SIZE = 4;
constexpr u32 AJM_INSTANCE_STATISTICS = 0x80000;
enum class AjmCodecType : u32 {
Mp3Dec = 0,
At9Dec = 1,
M4aacDec = 2,
Max = 23,
};
DECLARE_ENUM_FLAG_OPERATORS(AjmCodecType);
struct AjmBatchInfo {
void* pBuffer;
u64 offset;
u64 size;
};
struct AjmBatchError {
int error_code;
const void* job_addr;
u32 cmd_offset;
const void* job_ra;
};
struct AjmBuffer {
u8* p_address;
u64 size;
};
enum class AjmJobControlFlags : u64 {
Reset = 1 << 0,
Initialize = 1 << 1,
Resample = 1 << 2,
};
DECLARE_ENUM_FLAG_OPERATORS(AjmJobControlFlags)
enum class AjmJobRunFlags : u64 {
GetCodecInfo = 1 << 0,
MultipleFrames = 1 << 1,
};
DECLARE_ENUM_FLAG_OPERATORS(AjmJobRunFlags)
enum class AjmJobSidebandFlags : u64 {
GaplessDecode = 1 << 0,
Format = 1 << 1,
Stream = 1 << 2,
};
DECLARE_ENUM_FLAG_OPERATORS(AjmJobSidebandFlags)
union AjmJobFlags {
u64 raw;
struct {
u64 version : 3;
u64 codec : 8;
AjmJobRunFlags run_flags : 2;
AjmJobControlFlags control_flags : 3;
u64 reserved : 29;
AjmJobSidebandFlags sideband_flags : 3;
};
};
struct AjmSidebandResult {
s32 result;
s32 internal_result;
};
struct AjmSidebandMFrame {
u32 num_frames;
u32 reserved;
};
struct AjmSidebandStream {
s32 input_consumed;
s32 output_written;
u64 total_decoded_samples;
};
enum class AjmFormatEncoding : u32 {
S16 = 0,
S32 = 1,
Float = 2,
};
struct AjmSidebandFormat {
u32 num_channels;
u32 channel_mask;
u32 sampl_freq;
AjmFormatEncoding sample_encoding;
u32 bitrate;
u32 reserved;
};
struct AjmSidebandGaplessDecode {
u32 total_samples;
u16 skip_samples;
u16 skipped_samples;
};
struct AjmSidebandResampleParameters {
float ratio;
uint32_t flags;
};
struct AjmDecAt9InitializeParameters {
u8 config_data[ORBIS_AT9_CONFIG_DATA_SIZE];
u32 reserved;
};
union AjmSidebandInitParameters {
AjmDecAt9InitializeParameters at9;
u8 reserved[8];
};
union AjmInstanceFlags {
u64 raw;
struct {
u64 version : 3;
u64 channels : 4;
u64 format : 3;
u64 gapless_loop : 1;
u64 : 21;
u64 codec : 28;
};
};
struct AjmDecMp3ParseFrame;
int PS4_SYSV_ABI sceAjmBatchCancel(const u32 context_id, const u32 batch_id);
int PS4_SYSV_ABI sceAjmBatchErrorDump();
int PS4_SYSV_ABI sceAjmBatchJobControlBufferRa();
int PS4_SYSV_ABI sceAjmBatchJobInlineBuffer();
int PS4_SYSV_ABI sceAjmBatchJobRunBufferRa();
int PS4_SYSV_ABI sceAjmBatchJobRunSplitBufferRa();
int PS4_SYSV_ABI sceAjmBatchStartBuffer();
int PS4_SYSV_ABI sceAjmBatchWait();
void* PS4_SYSV_ABI sceAjmBatchJobControlBufferRa(void* p_buffer, u32 instance_id, u64 flags,
void* p_sideband_input, size_t sideband_input_size,
void* p_sideband_output,
size_t sideband_output_size,
void* p_return_address);
void* PS4_SYSV_ABI sceAjmBatchJobInlineBuffer(void* p_buffer, const void* p_data_input,
size_t data_input_size,
const void** pp_batch_address);
void* PS4_SYSV_ABI sceAjmBatchJobRunBufferRa(void* p_buffer, u32 instance_id, u64 flags,
void* p_data_input, size_t data_input_size,
void* p_data_output, size_t data_output_size,
void* p_sideband_output, size_t sideband_output_size,
void* p_return_address);
void* PS4_SYSV_ABI sceAjmBatchJobRunSplitBufferRa(
void* p_buffer, u32 instance_id, u64 flags, const AjmBuffer* p_data_input_buffers,
size_t num_data_input_buffers, const AjmBuffer* p_data_output_buffers,
size_t num_data_output_buffers, void* p_sideband_output, size_t sideband_output_size,
void* p_return_address);
int PS4_SYSV_ABI sceAjmBatchStartBuffer(u32 context, u8* batch, u32 batch_size, const int priority,
AjmBatchError* batch_error, u32* out_batch_id);
int PS4_SYSV_ABI sceAjmBatchWait(const u32 context, const u32 batch_id, const u32 timeout,
AjmBatchError* const batch_error);
int PS4_SYSV_ABI sceAjmDecAt9ParseConfigData();
int PS4_SYSV_ABI sceAjmDecMp3ParseFrame();
int PS4_SYSV_ABI sceAjmDecMp3ParseFrame(const u8* stream, u32 stream_size, int parse_ofl,
AjmDecMp3ParseFrame* frame);
int PS4_SYSV_ABI sceAjmFinalize();
int PS4_SYSV_ABI sceAjmInitialize();
int PS4_SYSV_ABI sceAjmInitialize(s64 reserved, u32* out_context);
int PS4_SYSV_ABI sceAjmInstanceCodecType();
int PS4_SYSV_ABI sceAjmInstanceCreate();
int PS4_SYSV_ABI sceAjmInstanceDestroy();
int PS4_SYSV_ABI sceAjmInstanceCreate(u32 context, AjmCodecType codec_type, AjmInstanceFlags flags,
u32* instance);
int PS4_SYSV_ABI sceAjmInstanceDestroy(u32 context, u32 instance);
int PS4_SYSV_ABI sceAjmInstanceExtend();
int PS4_SYSV_ABI sceAjmInstanceSwitch();
int PS4_SYSV_ABI sceAjmMemoryRegister();
int PS4_SYSV_ABI sceAjmMemoryUnregister();
int PS4_SYSV_ABI sceAjmModuleRegister();
int PS4_SYSV_ABI sceAjmModuleRegister(u32 context, AjmCodecType codec_type, s64 reserved);
int PS4_SYSV_ABI sceAjmModuleUnregister();
int PS4_SYSV_ABI sceAjmStrError();
void RegisterlibSceAjm(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Ajm
} // namespace Libraries::Ajm