Audio: split ACM, Audio3D, and NGS2 implementations

This commit is contained in:
nmzik
2026-09-23 19:04:39 +04:00
parent 3742ad9980
commit 1275d65bb3
9 changed files with 2743 additions and 2668 deletions
+177
View File
@@ -0,0 +1,177 @@
#include "libs/acm.h"
#include "common/assert.h"
#include "libs/errno.h"
#include "libs/libs.h"
#include <algorithm>
#include <atomic>
#include <cstring>
namespace Libs::Audio {
namespace Acm {
LIB_NAME("Acm", "Acm");
struct AcmBatchInfo {
void* buffer;
size_t offset;
size_t buffer_size;
};
struct AcmBatchError {
uint32_t reserved[8];
};
static std::atomic_uint32_t g_acm_next_context {1};
static std::atomic_uint32_t g_acm_next_batch {1};
static void acm_advance_batch(AcmBatchInfo* info, size_t bytes) {
if (info == nullptr || info->buffer == nullptr || info->buffer_size == 0) {
return;
}
info->offset = std::min(info->buffer_size, info->offset + bytes);
}
int KYTY_SYSV_ABI AcmContextCreate(AcmContextId* context) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(context == nullptr);
*context = g_acm_next_context.fetch_add(1, std::memory_order_relaxed);
LOGF("\t context = %" PRIu32 "\n", *context);
return OK;
}
int KYTY_SYSV_ABI AcmContextDestroy(AcmContextId context) {
PRINT_NAME();
LOGF("\t context = %" PRIu32 "\n", context);
return OK;
}
int KYTY_SYSV_ABI AcmBatchStartBuffer(AcmContextId context, const void* batch_commands,
size_t batch_size, AcmBatchError* batch_error,
AcmBatchId* batch) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(batch == nullptr);
if (batch_error != nullptr) {
std::memset(batch_error, 0, sizeof(AcmBatchError));
}
*batch = g_acm_next_batch.fetch_add(1, std::memory_order_relaxed);
return OK;
}
int KYTY_SYSV_ABI AcmBatchStartBuffers(AcmContextId context, uint32_t batch_info_count,
const AcmBatchInfo* const batch_info[],
AcmBatchError* batch_error, AcmBatchId* batch) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(batch_info_count != 0 && batch_info == nullptr);
EXIT_NOT_IMPLEMENTED(batch == nullptr);
if (batch_error != nullptr) {
std::memset(batch_error, 0, sizeof(AcmBatchError));
}
*batch = g_acm_next_batch.fetch_add(1, std::memory_order_relaxed);
return OK;
}
int KYTY_SYSV_ABI AcmBatchWait(AcmContextId context, AcmBatchId batch, uint32_t timeout) {
return OK;
}
int KYTY_SYSV_ABI AcmBatchJobNotification(AcmBatchInfo* batch_info) {
PRINT_NAME();
acm_advance_batch(batch_info, 2 * 16);
return OK;
}
int KYTY_SYSV_ABI AcmConvReverbSharedInput(AcmBatchInfo* batch_info, uint32_t block_count, void* in,
uint32_t count, const void* const ir[],
const float* gain, void* const out[]) {
PRINT_NAME();
(void)block_count;
(void)in;
(void)count;
(void)ir;
(void)gain;
(void)out;
acm_advance_batch(batch_info, 1024);
return OK;
}
int KYTY_SYSV_ABI AcmConvReverbSharedIr(AcmBatchInfo* batch_info, uint32_t block_count,
const void* ir, uint32_t count, void* const in[],
const float* gain, void* const out[]) {
PRINT_NAME();
(void)block_count;
(void)ir;
(void)count;
(void)in;
(void)gain;
(void)out;
acm_advance_batch(batch_info, 1024);
return OK;
}
int KYTY_SYSV_ABI AcmFft(AcmBatchInfo* batch_info, int size, int count, int input_format,
const void* const input[], int output_format, void* const output[],
uint32_t flags) {
PRINT_NAME();
(void)size;
(void)count;
(void)input_format;
(void)input;
(void)output_format;
(void)output;
(void)flags;
acm_advance_batch(batch_info, 256);
return OK;
}
int KYTY_SYSV_ABI AcmIfft(AcmBatchInfo* batch_info, int size, int count, int input_format,
const void* const input[], int output_format, void* const output[],
uint32_t flags) {
PRINT_NAME();
(void)size;
(void)count;
(void)input_format;
(void)input;
(void)output_format;
(void)output;
(void)flags;
acm_advance_batch(batch_info, 256);
return OK;
}
int KYTY_SYSV_ABI AcmPanner(AcmBatchInfo* batch_info, uint32_t in_count, const float* const in[],
uint32_t biquad_count, uint32_t biquad_update_count, uint32_t out_count,
const void* const parameter[], void* const state[],
const float* const out_init[], float* const out[]) {
PRINT_NAME();
(void)in_count;
(void)in;
(void)biquad_count;
(void)biquad_update_count;
(void)out_count;
(void)parameter;
(void)state;
(void)out_init;
(void)out;
acm_advance_batch(batch_info, 512);
return OK;
}
} // namespace Acm
} // namespace Libs::Audio
+48
View File
@@ -0,0 +1,48 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_LIBS_ACM_H_
#define EMULATOR_INCLUDE_EMULATOR_LIBS_ACM_H_
#include "common/abi.h"
#include "common/common.h"
namespace Libs::Audio {
namespace Acm {
struct AcmBatchInfo;
struct AcmBatchError;
using AcmContextId = uint32_t;
using AcmBatchId = uint32_t;
int KYTY_SYSV_ABI AcmContextCreate(AcmContextId* context);
int KYTY_SYSV_ABI AcmContextDestroy(AcmContextId context);
int KYTY_SYSV_ABI AcmBatchStartBuffer(AcmContextId context, const void* batch_commands,
size_t batch_size, AcmBatchError* batch_error,
AcmBatchId* batch);
int KYTY_SYSV_ABI AcmBatchStartBuffers(AcmContextId context, uint32_t batch_info_count,
const AcmBatchInfo* const batch_info[],
AcmBatchError* batch_error, AcmBatchId* batch);
int KYTY_SYSV_ABI AcmBatchWait(AcmContextId context, AcmBatchId batch, uint32_t timeout);
int KYTY_SYSV_ABI AcmBatchJobNotification(AcmBatchInfo* batch_info);
int KYTY_SYSV_ABI AcmConvReverbSharedInput(AcmBatchInfo* batch_info, uint32_t block_count, void* in,
uint32_t count, const void* const ir[],
const float* gain, void* const out[]);
int KYTY_SYSV_ABI AcmConvReverbSharedIr(AcmBatchInfo* batch_info, uint32_t block_count,
const void* ir, uint32_t count, void* const in[],
const float* gain, void* const out[]);
int KYTY_SYSV_ABI AcmFft(AcmBatchInfo* batch_info, int size, int count, int input_format,
const void* const input[], int output_format, void* const output[],
uint32_t flags);
int KYTY_SYSV_ABI AcmIfft(AcmBatchInfo* batch_info, int size, int count, int input_format,
const void* const input[], int output_format, void* const output[],
uint32_t flags);
int KYTY_SYSV_ABI AcmPanner(AcmBatchInfo* batch_info, uint32_t in_count, const float* const in[],
uint32_t biquad_count, uint32_t biquad_update_count, uint32_t out_count,
const void* const parameter[], void* const state[],
const float* const out_init[], float* const out[]);
} // namespace Acm
} // namespace Libs::Audio
#endif /* EMULATOR_INCLUDE_EMULATOR_LIBS_ACM_H_ */
-2542
View File
File diff suppressed because it is too large Load Diff
-126
View File
@@ -190,43 +190,6 @@ const char* KYTY_SYSV_ABI AjmStrError(int error);
} // namespace Ajm
namespace Acm {
struct AcmBatchInfo;
struct AcmBatchError;
using AcmContextId = uint32_t;
using AcmBatchId = uint32_t;
int KYTY_SYSV_ABI AcmContextCreate(AcmContextId* context);
int KYTY_SYSV_ABI AcmContextDestroy(AcmContextId context);
int KYTY_SYSV_ABI AcmBatchStartBuffer(AcmContextId context, const void* batch_commands,
size_t batch_size, AcmBatchError* batch_error,
AcmBatchId* batch);
int KYTY_SYSV_ABI AcmBatchStartBuffers(AcmContextId context, uint32_t batch_info_count,
const AcmBatchInfo* const batch_info[],
AcmBatchError* batch_error, AcmBatchId* batch);
int KYTY_SYSV_ABI AcmBatchWait(AcmContextId context, AcmBatchId batch, uint32_t timeout);
int KYTY_SYSV_ABI AcmBatchJobNotification(AcmBatchInfo* batch_info);
int KYTY_SYSV_ABI AcmConvReverbSharedInput(AcmBatchInfo* batch_info, uint32_t block_count, void* in,
uint32_t count, const void* const ir[],
const float* gain, void* const out[]);
int KYTY_SYSV_ABI AcmConvReverbSharedIr(AcmBatchInfo* batch_info, uint32_t block_count,
const void* ir, uint32_t count, void* const in[],
const float* gain, void* const out[]);
int KYTY_SYSV_ABI AcmFft(AcmBatchInfo* batch_info, int size, int count, int input_format,
const void* const input[], int output_format, void* const output[],
uint32_t flags);
int KYTY_SYSV_ABI AcmIfft(AcmBatchInfo* batch_info, int size, int count, int input_format,
const void* const input[], int output_format, void* const output[],
uint32_t flags);
int KYTY_SYSV_ABI AcmPanner(AcmBatchInfo* batch_info, uint32_t in_count, const float* const in[],
uint32_t biquad_count, uint32_t biquad_update_count, uint32_t out_count,
const void* const parameter[], void* const state[],
const float* const out_init[], float* const out[]);
} // namespace Acm
namespace AvPlayer {
struct AvPlayerInitData;
@@ -271,95 +234,6 @@ int KYTY_SYSV_ABI AvPlayerSetLogCallback(void* callback, void* user_data);
} // namespace AvPlayer
namespace Audio3d {
struct Audio3dOpenParameters;
int KYTY_SYSV_ABI Audio3dInitialize(int64_t reserved);
void KYTY_SYSV_ABI Audio3dGetDefaultOpenParameters(Audio3dOpenParameters* p);
int KYTY_SYSV_ABI Audio3dPortOpen(int user_id, const Audio3dOpenParameters* parameters,
uint32_t* id);
int KYTY_SYSV_ABI Audio3dPortSetAttribute(uint32_t port_id, uint32_t attribute_id,
const void* attribute, size_t attribute_size);
int KYTY_SYSV_ABI Audio3dPortGetQueueLevel(uint32_t port_id, uint32_t* queue_level,
uint32_t* queue_available);
int KYTY_SYSV_ABI Audio3dPortAdvance(uint32_t port_id);
int KYTY_SYSV_ABI Audio3dPortPush(uint32_t port_id, uint32_t blocking);
} // namespace Audio3d
namespace Ngs2 {
struct Ngs2SystemOption;
struct Ngs2SystemInfo;
struct Ngs2RackOption;
struct Ngs2BufferAllocator;
struct Ngs2VoiceParamHeader;
struct Ngs2RenderBufferInfo;
struct Ngs2ContextBufferInfo;
struct Ngs2VoiceState;
struct Ngs2WaveformFormat;
struct Ngs2WaveformBlock;
struct Ngs2WaveformInfo;
struct Ngs2PanWork;
struct Ngs2PanParam;
struct Ngs2GeomListenerParam;
struct Ngs2GeomListenerWork;
struct Ngs2GeomSourceParam;
struct Ngs2GeomAttribute;
int KYTY_SYSV_ABI Ngs2SystemResetOption(Ngs2SystemOption* option);
int KYTY_SYSV_ABI Ngs2SystemQueryBufferSize(const Ngs2SystemOption* option,
Ngs2ContextBufferInfo* buffer_info);
int KYTY_SYSV_ABI Ngs2SystemCreate(const Ngs2SystemOption* option,
const Ngs2ContextBufferInfo* buffer_info, uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2SystemGetInfo(uintptr_t system_handle, Ngs2SystemInfo* info,
size_t info_size);
int KYTY_SYSV_ABI Ngs2SystemSetGrainSamples(uintptr_t system_handle, uint32_t num_samples);
int KYTY_SYSV_ABI Ngs2RackQueryBufferSize(uint32_t rack_id, const Ngs2RackOption* option,
Ngs2ContextBufferInfo* buffer_info);
int KYTY_SYSV_ABI Ngs2RackCreate(uintptr_t system_handle, uint32_t rack_id,
const Ngs2RackOption* option,
const Ngs2ContextBufferInfo* buffer_info, uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2SystemCreateWithAllocator(const Ngs2SystemOption* option,
const Ngs2BufferAllocator* allocator,
uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2SystemDestroy(uintptr_t system_handle, Ngs2ContextBufferInfo* buffer_info);
int KYTY_SYSV_ABI Ngs2RackCreateWithAllocator(uintptr_t system_handle, uint32_t rack_id,
const Ngs2RackOption* option,
const Ngs2BufferAllocator* allocator,
uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2RackDestroy(uintptr_t rack_handle, Ngs2ContextBufferInfo* buffer_info);
int KYTY_SYSV_ABI Ngs2RackLock(uintptr_t rack_handle);
int KYTY_SYSV_ABI Ngs2RackUnlock(uintptr_t rack_handle);
int KYTY_SYSV_ABI Ngs2RackGetVoiceHandle(uintptr_t rack_handle, uint32_t voice_id,
uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2VoiceControl(uintptr_t voice_handle, const Ngs2VoiceParamHeader* param_list);
int KYTY_SYSV_ABI Ngs2VoiceRunCommands(uintptr_t voice_handle, const void* commands,
size_t num_commands);
int KYTY_SYSV_ABI Ngs2VoiceGetState(uintptr_t voice_handle, Ngs2VoiceState* state,
size_t state_size);
int KYTY_SYSV_ABI Ngs2VoiceGetStateFlags(uintptr_t voice_handle, uint32_t* state_flags);
int KYTY_SYSV_ABI Ngs2SystemRender(uintptr_t system_handle, const Ngs2RenderBufferInfo* buffer_info,
uint32_t num_buffer_info);
int KYTY_SYSV_ABI Ngs2ParseWaveformData(const void* data, size_t data_size, Ngs2WaveformInfo* info);
int KYTY_SYSV_ABI Ngs2CalcWaveformBlock(const Ngs2WaveformFormat* format, uint32_t sample_pos,
uint32_t num_samples, Ngs2WaveformBlock* block);
int KYTY_SYSV_ABI Ngs2PanInit(Ngs2PanWork* work, const float* speaker_angles, float unit_angle,
uint32_t num_speakers);
int KYTY_SYSV_ABI Ngs2PanGetVolumeMatrix(Ngs2PanWork* work, const Ngs2PanParam* params,
uint32_t num_params, uint32_t matrix_format,
float* out_volume_matrix);
int KYTY_SYSV_ABI Ngs2GeomResetListenerParam(Ngs2GeomListenerParam* out_listener_param);
int KYTY_SYSV_ABI Ngs2GeomResetSourceParam(Ngs2GeomSourceParam* out_source_param);
int KYTY_SYSV_ABI Ngs2GeomCalcListener(const Ngs2GeomListenerParam* param,
Ngs2GeomListenerWork* out_work, uint32_t flags);
int KYTY_SYSV_ABI Ngs2GeomApply(const Ngs2GeomListenerWork* listener,
const Ngs2GeomSourceParam* source, Ngs2GeomAttribute* out_attrib,
uint32_t flags);
} // namespace Ngs2
} // namespace Libs::Audio
#endif /* EMULATOR_INCLUDE_EMULATOR_AUDIO_H_ */
+319
View File
@@ -0,0 +1,319 @@
#include "libs/audio3d.h"
#include "common/assert.h"
#include "common/threads.h"
#include "kernel/semaphore.h"
#include "libs/errno.h"
#include "libs/libs.h"
#include <atomic>
namespace Libs::Audio {
namespace Audio3d {
LIB_NAME("Audio3d", "Audio3d");
namespace Semaphore = LibKernel::Semaphore;
struct Audio3dOpenParameters {
size_t size = 0x20;
uint32_t granularity = 256;
uint32_t rate = 0;
uint32_t max_objects = 512;
uint32_t queue_depth = 2;
uint32_t buffer_mode = 2;
uint32_t pad = 0;
// uint32_t num_beds;
};
struct Audio3dData {
enum class State { Empty, Ready, Play };
std::atomic<State> state = State::Empty;
};
struct Audio3dInternal {
Audio3dData* data = nullptr;
Common::Mutex* data_mutex = nullptr;
uint64_t data_delay = 0;
Semaphore::KernelSema playback_sema = nullptr;
Audio3dOpenParameters params = {};
int user_id = 0;
float late_reverb_level = 0.0f;
float downmix_spread_radius = 2.0f;
int downmix_spread_height_aware = 0;
uint32_t data_index = 0;
bool used = false;
std::atomic_bool playback_finished = false;
};
constexpr uint32_t MAX_PORTS = 4;
static Audio3dInternal g_ports[MAX_PORTS] = {};
static void playback_simulate(void* arg) {
auto* port = static_cast<Audio3dInternal*>(arg);
EXIT_IF(port == nullptr);
EXIT_IF(port->data_mutex == nullptr);
EXIT_IF(port->data == nullptr);
for (;;) {
int result = Semaphore::KernelWaitSema(port->playback_sema, 1, nullptr);
if (result != OK) {
break;
}
Audio3dData* play_data = nullptr;
port->data_mutex->Lock();
{
for (uint32_t i = 0; i < port->params.queue_depth; i++) {
uint32_t index = (port->data_index + i) % port->params.queue_depth;
if (port->data[index].state == Audio3dData::State::Play) {
play_data = &port->data[index];
break;
}
}
}
port->data_mutex->Unlock();
EXIT_IF(play_data == nullptr);
if (play_data != nullptr) {
// TODO(): Audio output is not yet implemented, so simulate audio delay
Common::Thread::SleepMicro(port->data_delay);
play_data->state = Audio3dData::State::Empty;
}
}
port->playback_finished = true;
}
int KYTY_SYSV_ABI Audio3dInitialize(int64_t reserved) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(reserved != 0);
return OK;
}
void KYTY_SYSV_ABI Audio3dGetDefaultOpenParameters(Audio3dOpenParameters* p) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(sizeof(Audio3dOpenParameters) != 0x20);
*p = Audio3dOpenParameters();
}
int KYTY_SYSV_ABI Audio3dPortOpen(int user_id, const Audio3dOpenParameters* parameters,
uint32_t* id) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(parameters == nullptr);
EXIT_NOT_IMPLEMENTED(id == nullptr);
EXIT_NOT_IMPLEMENTED(parameters->size != 0x20);
LOGF("\t user_id = %d\n"
"\t granularity = %u\n"
"\t rate = %u\n"
"\t max_objects = %u\n"
"\t queue_depth = %u\n"
"\t buffer_mode = %u\n",
user_id, parameters->granularity, parameters->rate, parameters->max_objects,
parameters->queue_depth, parameters->buffer_mode);
EXIT_NOT_IMPLEMENTED(parameters->buffer_mode != 2);
EXIT_NOT_IMPLEMENTED(user_id != 255 && user_id != 1);
uint32_t port = 0;
for (; port < MAX_PORTS; port++) {
if (!g_ports[port].used) {
break;
}
}
EXIT_NOT_IMPLEMENTED(port >= MAX_PORTS);
g_ports[port].user_id = user_id;
g_ports[port].params = *parameters;
g_ports[port].used = true;
EXIT_IF(g_ports[port].data != nullptr);
EXIT_IF(g_ports[port].data_mutex != nullptr);
EXIT_IF(g_ports[port].playback_sema != nullptr);
g_ports[port].data = new Audio3dData[parameters->queue_depth];
g_ports[port].data_index = 0;
g_ports[port].data_mutex = new Common::Mutex;
g_ports[port].data_delay = (1000000 * static_cast<uint64_t>(parameters->granularity)) / 48000;
for (uint32_t d = 0; d < parameters->queue_depth; d++) {
g_ports[port].data[d].state = Audio3dData::State::Empty;
}
int result = Semaphore::KernelCreateSema(&g_ports[port].playback_sema, "audio3d_play", 0x01, 0,
static_cast<int>(parameters->queue_depth), nullptr);
EXIT_NOT_IMPLEMENTED(result != OK);
g_ports[port].playback_finished = false;
Common::Thread playback_thread(playback_simulate, &g_ports[port]);
playback_thread.Detach();
*id = port;
return OK;
}
int KYTY_SYSV_ABI Audio3dPortSetAttribute(uint32_t port_id, uint32_t attribute_id,
const void* attribute, size_t attribute_size) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(port_id >= MAX_PORTS);
EXIT_NOT_IMPLEMENTED(!g_ports[port_id].used);
EXIT_NOT_IMPLEMENTED(attribute == nullptr);
LOGF("\t attribute_id = 0x%" PRIx32 "\n", attribute_id);
switch (attribute_id) {
case 0x10001:
EXIT_NOT_IMPLEMENTED(attribute_size != 4);
g_ports[port_id].late_reverb_level = *static_cast<const float*>(attribute);
LOGF("\t late_reverb_level = %f\n", g_ports[port_id].late_reverb_level);
break;
case 0x10002:
EXIT_NOT_IMPLEMENTED(attribute_size != 4);
g_ports[port_id].downmix_spread_radius = *static_cast<const float*>(attribute);
LOGF("\t downmix_spread_radius = %f\n", g_ports[port_id].downmix_spread_radius);
break;
case 0x10003:
EXIT_NOT_IMPLEMENTED(attribute_size != 4);
g_ports[port_id].downmix_spread_height_aware = *static_cast<const int*>(attribute);
LOGF("\t downmix_spread_height_aware = %d\n",
g_ports[port_id].downmix_spread_height_aware);
break;
default: EXIT("unknown attribute: 0x%" PRIx32 "\n", attribute_id);
}
return OK;
}
int KYTY_SYSV_ABI Audio3dPortGetQueueLevel(uint32_t port_id, uint32_t* queue_level,
uint32_t* queue_available) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(port_id >= MAX_PORTS);
EXIT_NOT_IMPLEMENTED(!g_ports[port_id].used);
EXIT_NOT_IMPLEMENTED(queue_level == nullptr && queue_available == nullptr);
auto* port = &g_ports[port_id];
uint32_t empty_num = 0;
port->data_mutex->Lock();
{
for (uint32_t i = 0; i < port->params.queue_depth; i++) {
uint32_t index = (port->data_index + i) % port->params.queue_depth;
if (port->data[index].state == Audio3dData::State::Empty) {
empty_num++;
} else {
break;
}
}
}
port->data_mutex->Unlock();
EXIT_IF(empty_num > port->params.queue_depth);
LOGF("\t queue_available = %u\n", empty_num);
if (queue_level != nullptr) {
*queue_level = port->params.queue_depth - empty_num;
}
if (queue_available != nullptr) {
*queue_available = empty_num;
}
return OK;
}
int KYTY_SYSV_ABI Audio3dPortAdvance(uint32_t port_id) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(port_id >= MAX_PORTS);
EXIT_NOT_IMPLEMENTED(!g_ports[port_id].used);
auto* port = &g_ports[port_id];
port->data_mutex->Lock();
{
uint32_t current_index = port->data_index;
uint32_t next_index = (current_index + 1) % port->params.queue_depth;
if (port->data[current_index].state == Audio3dData::State::Empty) {
port->data[current_index].state = Audio3dData::State::Ready;
}
EXIT_NOT_IMPLEMENTED(port->data[current_index].state != Audio3dData::State::Ready);
port->data_index = next_index;
LOGF("\t %u -> %u\n", current_index, next_index);
}
port->data_mutex->Unlock();
return OK;
}
int KYTY_SYSV_ABI Audio3dPortPush(uint32_t port_id, uint32_t blocking) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(port_id >= MAX_PORTS);
EXIT_NOT_IMPLEMENTED(!g_ports[port_id].used);
auto* port = &g_ports[port_id];
EXIT_NOT_IMPLEMENTED(blocking != 1);
LOGF("\t blocking = %u\n", blocking);
int data_num = 0;
Audio3dData* first_data = nullptr;
port->data_mutex->Lock();
{
first_data = port->data + port->data_index;
for (uint32_t i = 0; i < port->params.queue_depth; i++) {
uint32_t index = (port->data_index + i) % port->params.queue_depth;
if (port->data[index].state == Audio3dData::State::Ready) {
port->data[index].state = Audio3dData::State::Play;
data_num++;
}
}
}
port->data_mutex->Unlock();
LOGF("\t push num = %d\n", data_num);
if (data_num > 0) {
Semaphore::KernelSignalSema(port->playback_sema, data_num);
if (blocking == 1) {
auto wait_time = port->data_delay / 8;
while (first_data->state != Audio3dData::State::Empty) {
Common::Thread::SleepMicro(wait_time);
}
}
}
return OK;
}
} // namespace Audio3d
} // namespace Libs::Audio
+28
View File
@@ -0,0 +1,28 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_LIBS_AUDIO3D_H_
#define EMULATOR_INCLUDE_EMULATOR_LIBS_AUDIO3D_H_
#include "common/abi.h"
#include "common/common.h"
namespace Libs::Audio {
namespace Audio3d {
struct Audio3dOpenParameters;
int KYTY_SYSV_ABI Audio3dInitialize(int64_t reserved);
void KYTY_SYSV_ABI Audio3dGetDefaultOpenParameters(Audio3dOpenParameters* p);
int KYTY_SYSV_ABI Audio3dPortOpen(int user_id, const Audio3dOpenParameters* parameters,
uint32_t* id);
int KYTY_SYSV_ABI Audio3dPortSetAttribute(uint32_t port_id, uint32_t attribute_id,
const void* attribute, size_t attribute_size);
int KYTY_SYSV_ABI Audio3dPortGetQueueLevel(uint32_t port_id, uint32_t* queue_level,
uint32_t* queue_available);
int KYTY_SYSV_ABI Audio3dPortAdvance(uint32_t port_id);
int KYTY_SYSV_ABI Audio3dPortPush(uint32_t port_id, uint32_t blocking);
} // namespace Audio3d
} // namespace Libs::Audio
#endif /* EMULATOR_INCLUDE_EMULATOR_LIBS_AUDIO3D_H_ */
+3
View File
@@ -1,6 +1,9 @@
#include "common/abi.h"
#include "libs/ajm/aac_decoder.h"
#include "libs/acm.h"
#include "libs/audio3d.h"
#include "libs/audio.h"
#include "libs/ngs2.h"
#include "libs/libs.h"
#include "loader/symbolDatabase.h"
+2085
View File
File diff suppressed because it is too large Load Diff
+83
View File
@@ -0,0 +1,83 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_LIBS_NGS2_H_
#define EMULATOR_INCLUDE_EMULATOR_LIBS_NGS2_H_
#include "common/abi.h"
#include "common/common.h"
namespace Libs::Audio {
namespace Ngs2 {
struct Ngs2SystemOption;
struct Ngs2SystemInfo;
struct Ngs2RackOption;
struct Ngs2BufferAllocator;
struct Ngs2VoiceParamHeader;
struct Ngs2RenderBufferInfo;
struct Ngs2ContextBufferInfo;
struct Ngs2VoiceState;
struct Ngs2WaveformFormat;
struct Ngs2WaveformBlock;
struct Ngs2WaveformInfo;
struct Ngs2PanWork;
struct Ngs2PanParam;
struct Ngs2GeomListenerParam;
struct Ngs2GeomListenerWork;
struct Ngs2GeomSourceParam;
struct Ngs2GeomAttribute;
int KYTY_SYSV_ABI Ngs2SystemResetOption(Ngs2SystemOption* option);
int KYTY_SYSV_ABI Ngs2SystemQueryBufferSize(const Ngs2SystemOption* option,
Ngs2ContextBufferInfo* buffer_info);
int KYTY_SYSV_ABI Ngs2SystemCreate(const Ngs2SystemOption* option,
const Ngs2ContextBufferInfo* buffer_info, uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2SystemGetInfo(uintptr_t system_handle, Ngs2SystemInfo* info,
size_t info_size);
int KYTY_SYSV_ABI Ngs2SystemSetGrainSamples(uintptr_t system_handle, uint32_t num_samples);
int KYTY_SYSV_ABI Ngs2RackQueryBufferSize(uint32_t rack_id, const Ngs2RackOption* option,
Ngs2ContextBufferInfo* buffer_info);
int KYTY_SYSV_ABI Ngs2RackCreate(uintptr_t system_handle, uint32_t rack_id,
const Ngs2RackOption* option,
const Ngs2ContextBufferInfo* buffer_info, uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2SystemCreateWithAllocator(const Ngs2SystemOption* option,
const Ngs2BufferAllocator* allocator,
uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2SystemDestroy(uintptr_t system_handle, Ngs2ContextBufferInfo* buffer_info);
int KYTY_SYSV_ABI Ngs2RackCreateWithAllocator(uintptr_t system_handle, uint32_t rack_id,
const Ngs2RackOption* option,
const Ngs2BufferAllocator* allocator,
uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2RackDestroy(uintptr_t rack_handle, Ngs2ContextBufferInfo* buffer_info);
int KYTY_SYSV_ABI Ngs2RackLock(uintptr_t rack_handle);
int KYTY_SYSV_ABI Ngs2RackUnlock(uintptr_t rack_handle);
int KYTY_SYSV_ABI Ngs2RackGetVoiceHandle(uintptr_t rack_handle, uint32_t voice_id,
uintptr_t* handle);
int KYTY_SYSV_ABI Ngs2VoiceControl(uintptr_t voice_handle, const Ngs2VoiceParamHeader* param_list);
int KYTY_SYSV_ABI Ngs2VoiceRunCommands(uintptr_t voice_handle, const void* commands,
size_t num_commands);
int KYTY_SYSV_ABI Ngs2VoiceGetState(uintptr_t voice_handle, Ngs2VoiceState* state,
size_t state_size);
int KYTY_SYSV_ABI Ngs2VoiceGetStateFlags(uintptr_t voice_handle, uint32_t* state_flags);
int KYTY_SYSV_ABI Ngs2SystemRender(uintptr_t system_handle, const Ngs2RenderBufferInfo* buffer_info,
uint32_t num_buffer_info);
int KYTY_SYSV_ABI Ngs2ParseWaveformData(const void* data, size_t data_size, Ngs2WaveformInfo* info);
int KYTY_SYSV_ABI Ngs2CalcWaveformBlock(const Ngs2WaveformFormat* format, uint32_t sample_pos,
uint32_t num_samples, Ngs2WaveformBlock* block);
int KYTY_SYSV_ABI Ngs2PanInit(Ngs2PanWork* work, const float* speaker_angles, float unit_angle,
uint32_t num_speakers);
int KYTY_SYSV_ABI Ngs2PanGetVolumeMatrix(Ngs2PanWork* work, const Ngs2PanParam* params,
uint32_t num_params, uint32_t matrix_format,
float* out_volume_matrix);
int KYTY_SYSV_ABI Ngs2GeomResetListenerParam(Ngs2GeomListenerParam* out_listener_param);
int KYTY_SYSV_ABI Ngs2GeomResetSourceParam(Ngs2GeomSourceParam* out_source_param);
int KYTY_SYSV_ABI Ngs2GeomCalcListener(const Ngs2GeomListenerParam* param,
Ngs2GeomListenerWork* out_work, uint32_t flags);
int KYTY_SYSV_ABI Ngs2GeomApply(const Ngs2GeomListenerWork* listener,
const Ngs2GeomSourceParam* source, Ngs2GeomAttribute* out_attrib,
uint32_t flags);
} // namespace Ngs2
} // namespace Libs::Audio
#endif /* EMULATOR_INCLUDE_EMULATOR_LIBS_NGS2_H_ */