Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add audout:a audout:d aud:a aud:d #636

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions nx/include/switch/services/aud.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @file aud.h
* @brief Only available on [11.0.0+].
* @note Only one session may be open at once.
* @author TotalJustice
* @copyright libnx Authors
*/

#pragma once

#include "../types.h"
#include "../sf/service.h"

#define AUD_MAX_DELAY (1000000000ULL)

/// Initialize aud:a. Only available on [11.0.0+].
Result audaInitialize(void);

/// Exit aud:a.
void audaExit(void);

/// Initialize aud:d. Only available on [11.0.0+].
Result auddInitialize(void);

/// Exit aud:d.
void auddExit(void);

/// Gets the Service for aud:a.
Service* audaGetServiceSession(void);

/// Gets the Service for aud:d.
Service* auddGetServiceSession(void);

Result audaRequestSuspendAudio(u64 pid, u64 delay);
Result audaRequestResumeAudio(u64 pid, u64 delay);
Result audaGetAudioOutputProcessMasterVolume(u64 pid, float* volume_out);

Result audaSetAudioOutputProcessMasterVolume(u64 pid, u64 delay, float volume);
Result audaGetAudioInputProcessMasterVolume(u64 pid, float* volume_out);

// Sets both Output and Input volume
Result audaSetAudioInputProcessMasterVolume(u64 pid, u64 delay, float volume);
Result audaGetAudioOutputProcessRecordVolume(u64 pid, float* volume_out);
Result audaSetAudioOutputProcessRecordVolume(u64 pid, u64 delay, float volume);

Result auddRequestSuspendAudioForDebug(u64 pid, u64 delay);
Result auddRequestResumeAudioForDebug(u64 pid, u64 delay);
32 changes: 32 additions & 0 deletions nx/include/switch/services/audout.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "../audio/audio.h"
#include "../sf/service.h"

#define AUDOUT_MAX_DELAY (1000000000ULL)

typedef enum {
AudioOutState_Started = 0,
AudioOutState_Stopped = 1,
Expand All @@ -33,12 +35,30 @@ Result audoutInitialize(void);
/// Exit audout.
void audoutExit(void);

/// Initialize audout:a. Removed in [11.0.0].
Result audoutaInitialize(void);

/// Exit audout:a.
void audoutaExit(void);

/// Initialize audout:d. Removed in [11.0.0].
Result audoutdInitialize(void);

/// Exit audout:d.
void audoutdExit(void);

/// Gets the Service object for the actual audout service session.
Service* audoutGetServiceSession(void);

/// Gets the Service object for IAudioOut.
Service* audoutGetServiceSession_AudioOut(void);

/// Gets the Service for audout:a.
Service* audoutaGetServiceSession(void);

/// Gets the Service for audout:d.
Service* audoutdGetServiceSession(void);

Result audoutListAudioOuts(char *DeviceNames, s32 count, u32 *DeviceNamesCount);
Result audoutOpenAudioOut(const char *DeviceNameIn, char *DeviceNameOut, u32 SampleRateIn, u32 ChannelCountIn, u32 *SampleRateOut, u32 *ChannelCountOut, PcmFormat *Format, AudioOutState *State);
Result audoutGetAudioOutState(AudioOutState *State);
Expand Down Expand Up @@ -83,3 +103,15 @@ u32 audoutGetSampleRate(void); ///< Supported sample rate (
u32 audoutGetChannelCount(void); ///< Supported channel count (2 channels).
PcmFormat audoutGetPcmFormat(void); ///< Supported PCM format (Int16).
AudioOutState audoutGetDeviceState(void); ///< Initial device state (stopped).

Result audoutaRequestSuspendOld(u64 pid, u64 delay, Handle* handle_out); // [1.0.0] - [4.0.0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- [3.0.2]

Result audoutaRequestResumeOld(u64 pid, u64 delay, Handle* handle_out); // [1.0.0] - [4.0.0]
Result audoutaRequestSuspend(u64 pid, u64 delay); // [4.0.0]+
Result audoutaRequestResume(u64 pid, u64 delay); // [4.0.0]+
Result audoutaGetProcessMasterVolume(u64 pid, float* volume_out);
Result audoutaSetProcessMasterVolume(u64 pid, u64 delay, float volume);
Result audoutaGetProcessRecordVolume(u64 pid, float* volume_out);
Result audoutaSetProcessRecordVolume(u64 pid, u64 delay, float volume);

Result audoutdRequestSuspendForDebug(u64 pid, u64 delay);
Result audoutdRequestResumeForDebug(u64 pid, u64 delay);
115 changes: 115 additions & 0 deletions nx/source/services/aud.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#define NX_SERVICE_ASSUME_NON_DOMAIN
#include "service_guard.h"
#include "services/aud.h"
#include "runtime/hosversion.h"

static Service g_audaSrv;
static Service g_auddSrv;

NX_GENERATE_SERVICE_GUARD(auda);
NX_GENERATE_SERVICE_GUARD(audd);

Result _audaInitialize(void) {
if (hosversionBefore(11,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

return smGetService(&g_audaSrv, "aud:a");
}

void _audaCleanup(void) {
serviceClose(&g_audaSrv);
}

Result _auddInitialize(void) {
return smGetService(&g_auddSrv, "aud:d");
}

void _auddCleanup(void) {
serviceClose(&g_auddSrv);
}

Service* audaGetServiceSession(void) {
return &g_audaSrv;
}

Service* auddGetServiceSession(void) {
return &g_auddSrv;
}

Result audaRequestSuspendAudio(u64 pid, u64 delay) {
const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchIn(&g_audaSrv, 2, in);
}

Result audaRequestResumeAudio(u64 pid, u64 delay) {
const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchIn(&g_audaSrv, 3, in);
}

Result audaGetAudioOutputProcessMasterVolume(u64 pid, float* volume_out) {
return serviceDispatchInOut(&g_audaSrv, 4, pid, *volume_out);
}

Result audaSetAudioOutputProcessMasterVolume(u64 pid, u64 delay, float volume) {
const struct {
float volume;
u64 pid;
u64 delay;
} in = { volume, pid, delay };

return serviceDispatchIn(&g_audaSrv, 5, in);
}

Result audaGetAudioInputProcessMasterVolume(u64 pid, float* volume_out) {
return serviceDispatchInOut(&g_audaSrv, 6, pid, *volume_out);
}

Result audaSetAudioInputProcessMasterVolume(u64 pid, u64 delay, float volume) {
const struct {
float volume;
u64 pid;
u64 delay;
} in = { volume, pid, delay };

return serviceDispatchIn(&g_audaSrv, 7, in);
}

Result audaGetAudioOutputProcessRecordVolume(u64 pid, float* volume_out) {
return serviceDispatchInOut(&g_audaSrv, 8, pid, *volume_out);
}

Result audaSetAudioOutputProcessRecordVolume(u64 pid, u64 delay, float volume) {
const struct {
float volume;
u64 pid;
u64 delay;
} in = { volume, pid, delay };

return serviceDispatchIn(&g_audaSrv, 9, in);
}

Result auddRequestSuspendAudioForDebug(u64 pid, u64 delay) {
const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchIn(&g_auddSrv, 0, in);
}

Result auddRequestResumeAudioForDebug(u64 pid, u64 delay) {
const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchIn(&g_auddSrv, 1, in);
}
134 changes: 134 additions & 0 deletions nx/source/services/audout.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

static Service g_audoutSrv;
static Service g_audoutIAudioOut;
static Service g_audoutaSrv;
static Service g_audoutdSrv;

static Event g_audoutBufferEvent;

Expand All @@ -22,6 +24,8 @@ static AudioOutState g_deviceState = AudioOutState_Stopped;
static Result _audoutRegisterBufferEvent(Event *BufferEvent);

NX_GENERATE_SERVICE_GUARD(audout);
NX_GENERATE_SERVICE_GUARD(audouta);
NX_GENERATE_SERVICE_GUARD(audoutd);

Result _audoutInitialize(void) {
Result rc = 0;
Expand Down Expand Up @@ -56,6 +60,28 @@ void _audoutCleanup(void) {
serviceClose(&g_audoutSrv);
}

Result _audoutaInitialize(void) {
if (hosversionAtLeast(11,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

return smGetService(&g_audoutaSrv, "audout:a");
}

void _audoutaCleanup(void) {
serviceClose(&g_audoutaSrv);
}

Result _audoutdInitialize(void) {
if (hosversionAtLeast(11,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

return smGetService(&g_audoutdSrv, "audout:d");
}

void _audoutdCleanup(void) {
serviceClose(&g_audoutdSrv);
}

Service* audoutGetServiceSession(void) {
return &g_audoutSrv;
}
Expand All @@ -64,6 +90,14 @@ Service* audoutGetServiceSession_AudioOut(void) {
return &g_audoutIAudioOut;
}

Service* audoutaGetServiceSession(void) {
return &g_audoutaSrv;
}

Service* audoutdGetServiceSession(void) {
return &g_audoutdSrv;
}

u32 audoutGetSampleRate(void) {
return g_sampleRate;
}
Expand Down Expand Up @@ -259,3 +293,103 @@ Result audoutGetAudioOutVolume(float *volume) {

return serviceDispatchOut(&g_audoutIAudioOut, 13, *volume);
}

Result audoutaRequestSuspendOld(u64 pid, u64 delay, Handle* handle_out) {
if (hosversionAtLeast(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchInOut(&g_audoutaSrv, 0, in, *handle_out);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't correct for output-handle, see elsewhere.

}

Result audoutaRequestResumeOld(u64 pid, u64 delay, Handle* handle_out) {
if (hosversionAtLeast(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchInOut(&g_audoutaSrv, 1, in, *handle_out);
}

Result audoutaRequestSuspend(u64 pid, u64 delay) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchIn(&g_audoutaSrv, 0, in);
}

Result audoutaRequestResume(u64 pid, u64 delay) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchIn(&g_audoutaSrv, 1, in);
}

Result audoutaGetProcessMasterVolume(u64 pid, float* volume_out) {
return serviceDispatchInOut(&g_audoutaSrv, 2, pid, *volume_out);
}

Result audoutaSetProcessMasterVolume(u64 pid, u64 delay, float volume) {
const struct {
float volume;
u64 pid;
u64 delay;
} in = { volume, pid, delay };

return serviceDispatchIn(&g_audoutaSrv, 3, in);
}

Result audoutaGetProcessRecordVolume(u64 pid, float* volume_out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

return serviceDispatchInOut(&g_audoutaSrv, 4, pid, *volume_out);
}

Result audoutaSetProcessRecordVolume(u64 pid, u64 delay, float volume) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

const struct {
float volume;
u64 pid;
u64 delay;
} in = { volume, pid, delay };

return serviceDispatchIn(&g_audoutaSrv, 5, in);
}

Result audoutdRequestSuspendForDebug(u64 pid, u64 delay) {
const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchIn(&g_audoutdSrv, 0, in);
}

Result audoutdRequestResumeForDebug(u64 pid, u64 delay) {
const struct {
u64 pid;
u64 delay;
} in = { pid, delay };

return serviceDispatchIn(&g_audoutdSrv, 1, in);
}
Loading