audrec: Initial commit

This commit is contained in:
plutoo 2021-05-30 17:33:26 -07:00
parent a1ddefd3ca
commit 6ce881b013
2 changed files with 170 additions and 0 deletions

View File

@ -0,0 +1,47 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
u64 released_ns;
u64 next_buffer_ptr;
u64 sample_buffer_ptr;
u64 sample_buffer_capacity;
u64 data_size;
u64 data_offset;
} FinalOutputRecorderBuffer;
typedef struct {
u32 sample_rate;
u32 channel_count;
} FinalOutputRecorderParameter;
typedef struct {
u32 sample_rate;
u32 channel_count;
u32 sample_format;
u32 state;
} FinalOutputRecorderParameterInternal;
typedef struct {
Service s;
} AudrecRecorder;
Result audrecInitialize(void);
void audrecExit(void);
Service* audrecGetServiceSession(void);
Result audrecOpenFinalOutputRecorder(AudrecRecorder* recorder_out, FinalOutputRecorderParameter* param_in, u64 aruid, FinalOutputRecorderParameterInternal* param_out);
Result audrecRecorderStart(AudrecRecorder* recorder);
Result audrecRecorderStop(AudrecRecorder* recorder);
Result audrecRecorderRegisterBufferEvent(AudrecRecorder* recorder, Event* out_event);
Result audrecRecorderAppendFinalOutputRecorderBuffer(AudrecRecorder* recorder, u64 buffer_client_ptr, FinalOutputRecorderBuffer* param);
Result audrecRecorderGetReleasedFinalOutputRecorderBuffers(AudrecRecorder* recorder, u64* out_buffers, u64* inout_count, u64* out_released);
void audrecRecorderClose(AudrecRecorder* recorder);
#ifdef __cplusplus
};
#endif

123
nx/source/services/audrec.c Normal file
View File

@ -0,0 +1,123 @@
#define NX_SERVICE_ASSUME_NON_DOMAIN
#include "service_guard.h"
#include "kernel/event.h"
#include "runtime/hosversion.h"
#include "services/audrec.h"
NX_GENERATE_SERVICE_GUARD(audrec);
static Service g_audrecUserSrv;
Result _audrecInitialize(void) {
return smGetService(&g_audrecUserSrv, "audrec:u");
}
void _audrecCleanup(void) {
serviceClose(&g_audrecUserSrv);
}
Service* audrecGetServiceSession(void) {
return &g_audrecUserSrv;
}
Result audrecOpenFinalOutputRecorder(AudrecRecorder* recorder_out, FinalOutputRecorderParameter* param_in, u64 aruid, FinalOutputRecorderParameterInternal* param_out) {
const struct {
FinalOutputRecorderParameter param;
u64 aruid;
} in = { *param_in, aruid };
struct {
FinalOutputRecorderParameterInternal param;
} out;
Result rc = serviceDispatchInOut(&g_audrecUserSrv, 0, in, out,
.in_num_handles = 1,
.in_handles = { CUR_PROCESS_HANDLE },
.out_num_objects = 1,
.out_objects = &recorder_out->s,
);
if (R_SUCCEEDED(rc)) {
*param_out = out.param;
}
return rc;
}
Result audrecRecorderStart(AudrecRecorder* recorder) {
return serviceDispatch(&recorder->s, 1);
}
Result audrecRecorderStop(AudrecRecorder* recorder) {
return serviceDispatch(&recorder->s, 2);
}
Result audrecRecorderRegisterBufferEvent(AudrecRecorder* recorder, Event* out_event) {
Handle tmp_handle;
Result rc = serviceDispatch(&recorder->s, 4,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &tmp_handle,
);
if (R_SUCCEEDED(rc)) {
eventLoadRemote(out_event, tmp_handle, 1);
}
return rc;
}
Result audrecRecorderAppendFinalOutputRecorderBuffer(AudrecRecorder* recorder, u64 buffer_client_ptr, FinalOutputRecorderBuffer* param) {
const struct {
u64 buffer_client_ptr;
} in = { buffer_client_ptr };
if (hosversionAtLeast(3,0,0)) {
return serviceDispatchIn(&recorder->s, 8, in,
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_In },
.buffers = { { param, sizeof(*param) } },
);
}
else {
return serviceDispatchIn(&recorder->s, 3, in,
.buffer_attrs = { SfBufferAttr_In },
.buffers = { { param, sizeof(*param) } },
);
}
}
Result audrecRecorderGetReleasedFinalOutputRecorderBuffers(AudrecRecorder* recorder, u64* out_buffers, u64* inout_count, u64* out_released) {
struct {
u32 count;
u32 padding;
u64 released;
} out;
const struct {
} in;
Result rc;
if (hosversionAtLeast(3,0,0)) {
rc = serviceDispatchInOut(&recorder->s, 9, in, out,
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
.buffers = { { out_buffers, sizeof(u64) * (*inout_count) } },
);
}
else {
rc = serviceDispatchInOut(&recorder->s, 5, in, out,
.buffer_attrs = { SfBufferAttr_Out },
.buffers = { { out_buffers, sizeof(u64) * (*inout_count) } },
);
}
if (R_SUCCEEDED(rc)) {
*inout_count = out.count;
*out_released = out.released;
}
return rc;
}
void audrecRecorderClose(AudrecRecorder* recorder) {
serviceClose(&recorder->s);
}