diff --git a/nx/include/switch/services/applet.h b/nx/include/switch/services/applet.h index bcb68f1c..ca76b18c 100644 --- a/nx/include/switch/services/applet.h +++ b/nx/include/switch/services/applet.h @@ -611,6 +611,37 @@ Result appletSetAppletWindowVisibility(bool flag); */ Result appletSetAppletGpuTimeSlice(s64 val); +// IAudioController + +/** + * @brief Sets the ExpectedMasterVolume for MainApplet and LibraryApplet. + * @note Used by some official apps before/after launching LibraryApplets. Prior to changing the volume, the official app uses \ref appletGetExpectedMasterVolume, with the output being used to restore the volume after LibraryApplet handling. + * @param[in] mainAppletVolume MainApplet ExpectedMasterVolume. + * @param[in] libraryAppletVolume LibraryApplet ExpectedMasterVolume. + */ +Result appletSetExpectedMasterVolume(float mainAppletVolume, float libraryAppletVolume); + +/** + * @brief Gets the ExpectedMasterVolume for MainApplet and LibraryApplet. + * @note See also \ref appletSetExpectedMasterVolume. + * @param[out] mainAppletVolume MainApplet ExpectedMasterVolume. Optional, can be NULL. Used with cmd GetMainAppletExpectedMasterVolume when not NULL. + * @param[out] libraryAppletVolume LibraryApplet ExpectedMasterVolume. Optional, can be NULL. Used with cmd GetLibraryAppletExpectedMasterVolume when not NULL. + */ +Result appletGetExpectedMasterVolume(float *mainAppletVolume, float *libraryAppletVolume); + +/** + * @brief Change the MainApplet MasterVolume. + * @param[in] volume MainApplet MasterVolume. + * @param[in] unk Unknown. + */ +Result appletChangeMainAppletMasterVolume(float volume, u64 unk); + +/** + * @brief Sets the TransparentVolumeRate. + * @param[in] val Input value. + */ +Result appletSetTransparentVolumeRate(float val); + // ILibraryAppletCreator /** diff --git a/nx/source/services/applet.c b/nx/source/services/applet.c index 90e771c8..fe635864 100644 --- a/nx/source/services/applet.c +++ b/nx/source/services/applet.c @@ -1930,6 +1930,123 @@ Result appletSetAppletGpuTimeSlice(s64 val) { return _appletCmdInU64(&g_appletIWindowController, val, 21); } +// IAudioController + +Result appletSetExpectedMasterVolume(float mainAppletVolume, float libraryAppletVolume) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + float mainAppletVolume; + float libraryAppletVolume; + } *raw; + + raw = serviceIpcPrepareHeader(&g_appletIAudioController, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + raw->mainAppletVolume = mainAppletVolume; + raw->libraryAppletVolume = libraryAppletVolume; + + Result rc = serviceIpcDispatch(&g_appletIAudioController); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + } *resp; + + serviceIpcParse(&g_appletIAudioController, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result appletGetExpectedMasterVolume(float *mainAppletVolume, float *libraryAppletVolume) { + Result rc=0; + + if (mainAppletVolume) rc = _appletCmdNoInOut32(&g_appletIAudioController, (u32*)mainAppletVolume, 1); // GetMainAppletExpectedMasterVolume + if (R_SUCCEEDED(rc) && libraryAppletVolume) rc = _appletCmdNoInOut32(&g_appletIAudioController, (u32*)libraryAppletVolume, 2); // GetLibraryAppletExpectedMasterVolume + + return rc; +} + +Result appletChangeMainAppletMasterVolume(float volume, u64 unk) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + float volume; + u64 unk; + } *raw; + + raw = serviceIpcPrepareHeader(&g_appletIAudioController, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 3; + raw->volume = volume; + raw->unk = unk; + + Result rc = serviceIpcDispatch(&g_appletIAudioController); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + } *resp; + + serviceIpcParse(&g_appletIAudioController, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result appletSetTransparentVolumeRate(float val) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + float val; + } *raw; + + raw = serviceIpcPrepareHeader(&g_appletIAudioController, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 4; + raw->val = val; + + Result rc = serviceIpcDispatch(&g_appletIAudioController); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + } *resp; + + serviceIpcParse(&g_appletIAudioController, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + // ILibraryAppletCreator static Result _appletCreateLibraryApplet(Service* srv_out, AppletId id, LibAppletMode mode) {