mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-23 04:13:40 +00:00
Merge branch 'audio-add-new-functions-services' into 'master'
audio: Implement missing audio services and functions See merge request citron/rewrite!32
This commit is contained in:
@@ -539,6 +539,10 @@ add_library(core STATIC
|
||||
hle/service/audio/audio_renderer_manager.h
|
||||
hle/service/audio/audio_renderer.cpp
|
||||
hle/service/audio/audio_renderer.h
|
||||
hle/service/audio/audio_snoop_manager.cpp
|
||||
hle/service/audio/audio_snoop_manager.h
|
||||
hle/service/audio/audio_system_manager.cpp
|
||||
hle/service/audio/audio_system_manager.h
|
||||
hle/service/audio/audio.cpp
|
||||
hle/service/audio/audio.h
|
||||
hle/service/audio/codecctl.cpp
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "core/hle/service/audio/audio_in_manager.h"
|
||||
#include "core/hle/service/audio/audio_out_manager.h"
|
||||
#include "core/hle/service/audio/audio_renderer_manager.h"
|
||||
#include "core/hle/service/audio/audio_snoop_manager.h"
|
||||
#include "core/hle/service/audio/audio_system_manager.h"
|
||||
#include "core/hle/service/audio/codecctl.h"
|
||||
#include "core/hle/service/audio/final_output_recorder_manager.h"
|
||||
#include "core/hle/service/audio/final_output_recorder_manager_for_applet.h"
|
||||
@@ -50,9 +52,12 @@ void LoopProcess(Core::System& system) {
|
||||
// Debug service
|
||||
server_manager->RegisterNamedService("auddebug", std::make_shared<IAudioDebugManager>(system));
|
||||
|
||||
// System-level audio services
|
||||
server_manager->RegisterNamedService("aud:a", std::make_shared<IAudioController>(system)); // System version of audctl
|
||||
server_manager->RegisterNamedService("aud:d", std::make_shared<IAudioDeviceService>(system, "aud:d")); // System device service
|
||||
// Audio snoop service (auddev)
|
||||
server_manager->RegisterNamedService("auddev", std::make_shared<IAudioSnoopManager>(system));
|
||||
|
||||
// System-level audio services [11.0.0+]
|
||||
server_manager->RegisterNamedService("aud:a", std::make_shared<IAudioSystemManagerForApplet>(system)); // System manager for applet
|
||||
server_manager->RegisterNamedService("aud:d", std::make_shared<IAudioSystemManagerForDebugger>(system)); // System manager for debugger
|
||||
|
||||
ServerManager::RunServer(std::move(server_manager));
|
||||
}
|
||||
|
||||
@@ -69,6 +69,11 @@ IAudioController::IAudioController(Core::System& system_)
|
||||
{10105, D<&IAudioController::BindAudioOutputChannelCountUpdateEventForPlayReport>, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
|
||||
{10106, D<&IAudioController::GetDefaultAudioOutputTargetForPlayReport>, "GetDefaultAudioOutputTargetForPlayReport"},
|
||||
{50000, D<&IAudioController::SetAnalogInputBoostGainForPrototyping>, "SetAnalogInputBoostGainForPrototyping"},
|
||||
{50001, D<&IAudioController::OverrideDefaultTargetForDebug>, "OverrideDefaultTargetForDebug"}, // [19.0.0-19.0.1]
|
||||
{50003, D<&IAudioController::SetForceOverrideExternalDeviceNameForDebug>, "SetForceOverrideExternalDeviceNameForDebug"}, // [19.0.0+]
|
||||
{50004, D<&IAudioController::ClearForceOverrideExternalDeviceNameForDebug>, "ClearForceOverrideExternalDeviceNameForDebug"}, // [19.0.0+]
|
||||
{5000, nullptr, "Unknown5000"}, // [19.0.0+]
|
||||
{10200, nullptr, "Unknown10200"}, // [20.0.0+]
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -328,8 +333,9 @@ Result IAudioController::IsHearingProtectionSafeguardMonitoringOutputForDebug(Ou
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioController::GetSystemInformationForDebug(OutLargeData<u8, BufferAttr_HipcMapAlias> out_info) {
|
||||
Result IAudioController::GetSystemInformationForDebug(OutLargeData<std::array<u8, 0x400>, BufferAttr_HipcMapAlias> out_info) {
|
||||
LOG_WARNING(Audio, "(STUBBED) called");
|
||||
std::memset(out_info->data(), 0, out_info->size());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -381,4 +387,19 @@ Result IAudioController::SetAnalogInputBoostGainForPrototyping(f32 gain) {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioController::OverrideDefaultTargetForDebug(u32 target) {
|
||||
LOG_WARNING(Audio, "(STUBBED) called, target={}", target);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioController::SetForceOverrideExternalDeviceNameForDebug(InLargeData<std::array<u8, 0x80>, BufferAttr_HipcMapAlias> device_name) {
|
||||
LOG_WARNING(Audio, "(STUBBED) called, device_name size={}", device_name->size());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioController::ClearForceOverrideExternalDeviceNameForDebug() {
|
||||
LOG_WARNING(Audio, "(STUBBED) called");
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::Audio
|
||||
|
||||
@@ -77,7 +77,7 @@ private:
|
||||
Result SetHearingProtectionSafeguardEnabled(bool is_enabled);
|
||||
Result IsHearingProtectionSafeguardEnabled(Out<bool> out_is_enabled);
|
||||
Result IsHearingProtectionSafeguardMonitoringOutputForDebug(Out<bool> out_is_monitoring);
|
||||
Result GetSystemInformationForDebug(OutLargeData<u8, BufferAttr_HipcMapAlias> out_info);
|
||||
Result GetSystemInformationForDebug(OutLargeData<std::array<u8, 0x400>, BufferAttr_HipcMapAlias> out_info);
|
||||
Result SetVolumeButtonLongPressTime(u64 long_press_time);
|
||||
Result SetNativeVolumeForDebug(f32 native_volume);
|
||||
Result NotifyAudioOutputTargetForPlayReport(u32 target);
|
||||
@@ -87,6 +87,9 @@ private:
|
||||
Result BindAudioOutputTargetUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
Result GetDefaultAudioOutputTargetForPlayReport(Out<u32> out_target);
|
||||
Result SetAnalogInputBoostGainForPrototyping(f32 gain);
|
||||
Result OverrideDefaultTargetForDebug(u32 target); // [19.0.0-19.0.1]
|
||||
Result SetForceOverrideExternalDeviceNameForDebug(InLargeData<std::array<u8, 0x80>, BufferAttr_HipcMapAlias> device_name); // [19.0.0+]
|
||||
Result ClearForceOverrideExternalDeviceNameForDebug(); // [19.0.0+]
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
|
||||
|
||||
@@ -31,6 +31,12 @@ IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u
|
||||
{12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"},
|
||||
{13, D<&IAudioDevice::GetActiveAudioOutputDeviceName>, "GetActiveAudioOutputDeviceName"},
|
||||
{14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"},
|
||||
{15, D<&IAudioDevice::AcquireAudioInputDeviceNotification>, "AcquireAudioInputDeviceNotification"}, // [17.0.0+]
|
||||
{16, D<&IAudioDevice::ReleaseAudioInputDeviceNotification>, "ReleaseAudioInputDeviceNotification"}, // [17.0.0+]
|
||||
{17, D<&IAudioDevice::AcquireAudioOutputDeviceNotification>, "AcquireAudioOutputDeviceNotification"}, // [17.0.0+]
|
||||
{18, D<&IAudioDevice::ReleaseAudioOutputDeviceNotification>, "ReleaseAudioOutputDeviceNotification"}, // [17.0.0+]
|
||||
{19, D<&IAudioDevice::SetAudioDeviceOutputVolumeAutoTuneEnabled>, "SetAudioDeviceOutputVolumeAutoTuneEnabled"}, // [18.0.0+]
|
||||
{20, D<&IAudioDevice::IsAudioDeviceOutputVolumeAutoTuneEnabled>, "IsAudioDeviceOutputVolumeAutoTuneEnabled"}, // [18.0.0+]
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -173,4 +179,37 @@ Result IAudioDevice::ListAudioOutputDeviceName(
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioDevice::AcquireAudioInputDeviceNotification(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
*out_event = &event->GetReadableEvent();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioDevice::ReleaseAudioInputDeviceNotification(InCopyHandle<Kernel::KReadableEvent> notification_event) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioDevice::AcquireAudioOutputDeviceNotification(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
*out_event = &event->GetReadableEvent();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioDevice::ReleaseAudioOutputDeviceNotification(InCopyHandle<Kernel::KReadableEvent> notification_event) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioDevice::SetAudioDeviceOutputVolumeAutoTuneEnabled(bool enabled) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called, enabled={}", enabled);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioDevice::IsAudioDeviceOutputVolumeAutoTuneEnabled(Out<bool> out_enabled) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
*out_enabled = false;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::Audio
|
||||
|
||||
@@ -53,6 +53,12 @@ private:
|
||||
Result ListAudioOutputDeviceName(
|
||||
OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names,
|
||||
Out<s32> out_count);
|
||||
Result AcquireAudioInputDeviceNotification(OutCopyHandle<Kernel::KReadableEvent> out_event); // [17.0.0+]
|
||||
Result ReleaseAudioInputDeviceNotification(InCopyHandle<Kernel::KReadableEvent> notification_event); // [17.0.0+]
|
||||
Result AcquireAudioOutputDeviceNotification(OutCopyHandle<Kernel::KReadableEvent> out_event); // [17.0.0+]
|
||||
Result ReleaseAudioOutputDeviceNotification(InCopyHandle<Kernel::KReadableEvent> notification_event); // [17.0.0+]
|
||||
Result SetAudioDeviceOutputVolumeAutoTuneEnabled(bool enabled); // [18.0.0+]
|
||||
Result IsAudioDeviceOutputVolumeAutoTuneEnabled(Out<bool> out_enabled); // [18.0.0+]
|
||||
|
||||
KernelHelpers::ServiceContext service_context;
|
||||
std::unique_ptr<AudioCore::Renderer::AudioDevice> impl;
|
||||
|
||||
98
src/core/hle/service/audio/audio_snoop_manager.cpp
Normal file
98
src/core/hle/service/audio/audio_snoop_manager.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/service/audio/audio_snoop_manager.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
IAudioSnoopManager::IAudioSnoopManager(Core::System& system_)
|
||||
: ServiceFramework{system_, "auddev"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioSnoopManager::EnableDspUsageMeasurement>, "EnableDspUsageMeasurement"}, // [6.0.0-16.1.0] / [17.0.0+] GetDspStatistics
|
||||
{1, D<&IAudioSnoopManager::DisableDspUsageMeasurement>, "DisableDspUsageMeasurement"}, // [6.0.0-16.1.0] / [20.0.0+] GetAppletStateSummaries
|
||||
{2, D<&IAudioSnoopManager::SetDspStatisticsParameter>, "SetDspStatisticsParameter"}, // [20.0.0+]
|
||||
{3, D<&IAudioSnoopManager::GetDspStatisticsParameter>, "GetDspStatisticsParameter"}, // [20.0.0+]
|
||||
{6, D<&IAudioSnoopManager::GetDspUsage>, "GetDspUsage"}, // [6.0.0-16.1.0]
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IAudioSnoopManager::~IAudioSnoopManager() = default;
|
||||
|
||||
Result IAudioSnoopManager::EnableDspUsageMeasurement() {
|
||||
LOG_INFO(Service_Audio, "called");
|
||||
|
||||
// [6.0.0-16.1.0] EnableDspUsageMeasurement
|
||||
dsp_usage_measurement_enabled = true;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSnoopManager::GetDspStatistics(Out<u64> out_statistics) {
|
||||
LOG_INFO(Service_Audio, "called");
|
||||
|
||||
// [17.0.0+] GetDspStatistics
|
||||
*out_statistics = dsp_statistics;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSnoopManager::DisableDspUsageMeasurement() {
|
||||
LOG_INFO(Service_Audio, "called");
|
||||
|
||||
// [6.0.0-16.1.0] DisableDspUsageMeasurement
|
||||
dsp_usage_measurement_enabled = false;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSnoopManager::GetAppletStateSummaries(OutLargeData<std::array<u8, 0x1000>, BufferAttr_HipcMapAlias> out_summaries) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
// [20.0.0+] GetAppletStateSummaries
|
||||
// This function returns applet state summaries in a buffer
|
||||
// Since we don't have real applet state tracking, return empty data
|
||||
std::memset(out_summaries->data(), 0, out_summaries->size());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSnoopManager::SetDspStatisticsParameter(InLargeData<std::array<u8, 0x100>, BufferAttr_HipcMapAlias> parameter) {
|
||||
LOG_INFO(Service_Audio, "called with parameter size {}", parameter->size());
|
||||
|
||||
// [20.0.0+] SetDspStatisticsParameter
|
||||
// Copy the parameter data to our internal buffer
|
||||
const size_t copy_size = std::min(parameter->size(), dsp_statistics_parameter.size());
|
||||
std::memcpy(dsp_statistics_parameter.data(), parameter->data(), copy_size);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSnoopManager::GetDspStatisticsParameter(OutLargeData<std::array<u8, 0x100>, BufferAttr_HipcMapAlias> out_parameter) {
|
||||
LOG_INFO(Service_Audio, "called");
|
||||
|
||||
// [20.0.0+] GetDspStatisticsParameter
|
||||
// Return the stored parameter data
|
||||
const size_t copy_size = std::min(out_parameter->size(), dsp_statistics_parameter.size());
|
||||
std::memcpy(out_parameter->data(), dsp_statistics_parameter.data(), copy_size);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSnoopManager::GetDspUsage(Out<u64> out_usage) {
|
||||
LOG_INFO(Service_Audio, "called");
|
||||
|
||||
// [6.0.0-16.1.0] GetDspUsage
|
||||
*out_usage = dsp_usage;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::Audio
|
||||
45
src/core/hle/service/audio/audio_snoop_manager.h
Normal file
45
src/core/hle/service/audio/audio_snoop_manager.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
class IAudioSnoopManager final : public ServiceFramework<IAudioSnoopManager> {
|
||||
public:
|
||||
explicit IAudioSnoopManager(Core::System& system_);
|
||||
~IAudioSnoopManager() override;
|
||||
|
||||
private:
|
||||
// [6.0.0-16.1.0] EnableDspUsageMeasurement / [17.0.0+] GetDspStatistics
|
||||
Result EnableDspUsageMeasurement();
|
||||
Result GetDspStatistics(Out<u64> out_statistics);
|
||||
|
||||
// [6.0.0-16.1.0] DisableDspUsageMeasurement / [20.0.0+] GetAppletStateSummaries
|
||||
Result DisableDspUsageMeasurement();
|
||||
Result GetAppletStateSummaries(OutLargeData<std::array<u8, 0x1000>, BufferAttr_HipcMapAlias> out_summaries);
|
||||
|
||||
// [20.0.0+] SetDspStatisticsParameter
|
||||
Result SetDspStatisticsParameter(InLargeData<std::array<u8, 0x100>, BufferAttr_HipcMapAlias> parameter);
|
||||
|
||||
// [20.0.0+] GetDspStatisticsParameter
|
||||
Result GetDspStatisticsParameter(OutLargeData<std::array<u8, 0x100>, BufferAttr_HipcMapAlias> out_parameter);
|
||||
|
||||
// [6.0.0-16.1.0] GetDspUsage
|
||||
Result GetDspUsage(Out<u64> out_usage);
|
||||
|
||||
// State variables
|
||||
bool dsp_usage_measurement_enabled{false};
|
||||
u64 dsp_statistics{0};
|
||||
u64 dsp_usage{0};
|
||||
std::array<u8, 0x100> dsp_statistics_parameter{};
|
||||
};
|
||||
|
||||
} // namespace Service::Audio
|
||||
174
src/core/hle/service/audio/audio_system_manager.cpp
Normal file
174
src/core/hle/service/audio/audio_system_manager.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/service/audio/audio_system_manager.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
// IAudioSystemManagerForApplet implementation
|
||||
IAudioSystemManagerForApplet::IAudioSystemManagerForApplet(Core::System& system_)
|
||||
: ServiceFramework{system_, "aud:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioSystemManagerForApplet::RegisterAppletResourceUserId>, "RegisterAppletResourceUserId"},
|
||||
{1, D<&IAudioSystemManagerForApplet::UnregisterAppletResourceUserId>, "UnregisterAppletResourceUserId"},
|
||||
{2, D<&IAudioSystemManagerForApplet::RequestSuspendAudio>, "RequestSuspendAudio"},
|
||||
{3, D<&IAudioSystemManagerForApplet::RequestResumeAudio>, "RequestResumeAudio"},
|
||||
{4, D<&IAudioSystemManagerForApplet::GetAudioOutputProcessMasterVolume>, "GetAudioOutputProcessMasterVolume"},
|
||||
{5, D<&IAudioSystemManagerForApplet::SetAudioOutputProcessMasterVolume>, "SetAudioOutputProcessMasterVolume"},
|
||||
{6, D<&IAudioSystemManagerForApplet::GetAudioInputProcessMasterVolume>, "GetAudioInputProcessMasterVolume"},
|
||||
{7, D<&IAudioSystemManagerForApplet::SetAudioInputProcessMasterVolume>, "SetAudioInputProcessMasterVolume"},
|
||||
{8, D<&IAudioSystemManagerForApplet::GetAudioOutputProcessRecordVolume>, "GetAudioOutputProcessRecordVolume"},
|
||||
{9, D<&IAudioSystemManagerForApplet::SetAudioOutputProcessRecordVolume>, "SetAudioOutputProcessRecordVolume"},
|
||||
{10, D<&IAudioSystemManagerForApplet::GetAppletStateSummaries>, "GetAppletStateSummaries"}, // [18.0.0-19.0.1]
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IAudioSystemManagerForApplet::~IAudioSystemManagerForApplet() = default;
|
||||
|
||||
Result IAudioSystemManagerForApplet::RegisterAppletResourceUserId(u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
registered_applets[applet_resource_user_id] = true;
|
||||
// Set default volumes
|
||||
applet_output_volumes[applet_resource_user_id] = 1.0f;
|
||||
applet_input_volumes[applet_resource_user_id] = 1.0f;
|
||||
applet_record_volumes[applet_resource_user_id] = 1.0f;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::UnregisterAppletResourceUserId(u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
registered_applets.erase(applet_resource_user_id);
|
||||
applet_output_volumes.erase(applet_resource_user_id);
|
||||
applet_input_volumes.erase(applet_resource_user_id);
|
||||
applet_record_volumes.erase(applet_resource_user_id);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::RequestSuspendAudio(u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
// Mark as suspended for this applet
|
||||
if (registered_applets.find(applet_resource_user_id) != registered_applets.end()) {
|
||||
registered_applets[applet_resource_user_id] = false;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::RequestResumeAudio(u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
// Mark as resumed for this applet
|
||||
if (registered_applets.find(applet_resource_user_id) != registered_applets.end()) {
|
||||
registered_applets[applet_resource_user_id] = true;
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::GetAudioOutputProcessMasterVolume(Out<f32> out_volume, u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
const auto it = applet_output_volumes.find(applet_resource_user_id);
|
||||
*out_volume = (it != applet_output_volumes.end()) ? it->second : 1.0f;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::SetAudioOutputProcessMasterVolume(f32 volume, u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, volume={}, applet_resource_user_id={:#x}", volume, applet_resource_user_id);
|
||||
|
||||
applet_output_volumes[applet_resource_user_id] = std::clamp(volume, 0.0f, 1.0f);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::GetAudioInputProcessMasterVolume(Out<f32> out_volume, u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
const auto it = applet_input_volumes.find(applet_resource_user_id);
|
||||
*out_volume = (it != applet_input_volumes.end()) ? it->second : 1.0f;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::SetAudioInputProcessMasterVolume(f32 volume, u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, volume={}, applet_resource_user_id={:#x}", volume, applet_resource_user_id);
|
||||
|
||||
applet_input_volumes[applet_resource_user_id] = std::clamp(volume, 0.0f, 1.0f);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::GetAudioOutputProcessRecordVolume(Out<f32> out_volume, u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
const auto it = applet_record_volumes.find(applet_resource_user_id);
|
||||
*out_volume = (it != applet_record_volumes.end()) ? it->second : 1.0f;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::SetAudioOutputProcessRecordVolume(f32 volume, u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, volume={}, applet_resource_user_id={:#x}", volume, applet_resource_user_id);
|
||||
|
||||
applet_record_volumes[applet_resource_user_id] = std::clamp(volume, 0.0f, 1.0f);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForApplet::GetAppletStateSummaries(OutLargeData<std::array<u8, 0x1000>, BufferAttr_HipcMapAlias> out_summaries) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
// [18.0.0-19.0.1] GetAppletStateSummaries
|
||||
// This function returns applet state summaries in a buffer
|
||||
// Since we don't have real applet state tracking, return empty data
|
||||
std::memset(out_summaries->data(), 0, out_summaries->size());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
// IAudioSystemManagerForDebugger implementation
|
||||
IAudioSystemManagerForDebugger::IAudioSystemManagerForDebugger(Core::System& system_)
|
||||
: ServiceFramework{system_, "aud:d"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, D<&IAudioSystemManagerForDebugger::RequestSuspendAudioForDebug>, "RequestSuspendAudioForDebug"},
|
||||
{1, D<&IAudioSystemManagerForDebugger::RequestResumeAudioForDebug>, "RequestResumeAudioForDebug"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IAudioSystemManagerForDebugger::~IAudioSystemManagerForDebugger() = default;
|
||||
|
||||
Result IAudioSystemManagerForDebugger::RequestSuspendAudioForDebug(u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
suspended_applets[applet_resource_user_id] = true;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IAudioSystemManagerForDebugger::RequestResumeAudioForDebug(u64 applet_resource_user_id) {
|
||||
LOG_INFO(Service_Audio, "called, applet_resource_user_id={:#x}", applet_resource_user_id);
|
||||
|
||||
suspended_applets[applet_resource_user_id] = false;
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
} // namespace Service::Audio
|
||||
55
src/core/hle/service/audio/audio_system_manager.h
Normal file
55
src/core/hle/service/audio/audio_system_manager.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
// This is "nn::audio::detail::IAudioSystemManagerForApplet" added with [11.0.0+]
|
||||
class IAudioSystemManagerForApplet final : public ServiceFramework<IAudioSystemManagerForApplet> {
|
||||
public:
|
||||
explicit IAudioSystemManagerForApplet(Core::System& system_);
|
||||
~IAudioSystemManagerForApplet() override;
|
||||
|
||||
private:
|
||||
Result RegisterAppletResourceUserId(u64 applet_resource_user_id);
|
||||
Result UnregisterAppletResourceUserId(u64 applet_resource_user_id);
|
||||
Result RequestSuspendAudio(u64 applet_resource_user_id);
|
||||
Result RequestResumeAudio(u64 applet_resource_user_id);
|
||||
Result GetAudioOutputProcessMasterVolume(Out<f32> out_volume, u64 applet_resource_user_id);
|
||||
Result SetAudioOutputProcessMasterVolume(f32 volume, u64 applet_resource_user_id);
|
||||
Result GetAudioInputProcessMasterVolume(Out<f32> out_volume, u64 applet_resource_user_id);
|
||||
Result SetAudioInputProcessMasterVolume(f32 volume, u64 applet_resource_user_id);
|
||||
Result GetAudioOutputProcessRecordVolume(Out<f32> out_volume, u64 applet_resource_user_id);
|
||||
Result SetAudioOutputProcessRecordVolume(f32 volume, u64 applet_resource_user_id);
|
||||
Result GetAppletStateSummaries(OutLargeData<std::array<u8, 0x1000>, BufferAttr_HipcMapAlias> out_summaries); // [18.0.0-19.0.1]
|
||||
|
||||
// State variables
|
||||
std::map<u64, bool> registered_applets;
|
||||
std::map<u64, f32> applet_output_volumes;
|
||||
std::map<u64, f32> applet_input_volumes;
|
||||
std::map<u64, f32> applet_record_volumes;
|
||||
};
|
||||
|
||||
// This is "nn::audio::detail::IAudioSystemManagerForDebugger" added with [11.0.0+]
|
||||
class IAudioSystemManagerForDebugger final : public ServiceFramework<IAudioSystemManagerForDebugger> {
|
||||
public:
|
||||
explicit IAudioSystemManagerForDebugger(Core::System& system_);
|
||||
~IAudioSystemManagerForDebugger() override;
|
||||
|
||||
private:
|
||||
Result RequestSuspendAudioForDebug(u64 applet_resource_user_id);
|
||||
Result RequestResumeAudioForDebug(u64 applet_resource_user_id);
|
||||
|
||||
// State variables
|
||||
std::map<u64, bool> suspended_applets;
|
||||
};
|
||||
|
||||
} // namespace Service::Audio
|
||||
Reference in New Issue
Block a user