diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index cb46c8653..8f1234481 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -515,8 +515,12 @@ add_library(core STATIC hle/service/apm/apm_interface.h hle/service/audio/audio_controller.cpp hle/service/audio/audio_controller.h + hle/service/audio/audio_debug.cpp + hle/service/audio/audio_debug.h hle/service/audio/audio_device.cpp hle/service/audio/audio_device.h + hle/service/audio/audio_device_service.cpp + hle/service/audio/audio_device_service.h hle/service/audio/audio_in_manager.cpp hle/service/audio/audio_in_manager.h hle/service/audio/audio_in.cpp @@ -531,6 +535,8 @@ add_library(core STATIC hle/service/audio/audio_renderer.h hle/service/audio/audio.cpp hle/service/audio/audio.h + hle/service/audio/codecctl.cpp + hle/service/audio/codecctl.h hle/service/audio/errors.h hle/service/audio/final_output_recorder_manager_for_applet.cpp hle/service/audio/final_output_recorder_manager_for_applet.h diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index 331176bf7..52861eb5c 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp @@ -1,12 +1,16 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" #include "core/hle/service/audio/audio.h" #include "core/hle/service/audio/audio_controller.h" +#include "core/hle/service/audio/audio_debug.h" +#include "core/hle/service/audio/audio_device_service.h" #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/codecctl.h" #include "core/hle/service/audio/final_output_recorder_manager.h" #include "core/hle/service/audio/final_output_recorder_manager_for_applet.h" #include "core/hle/service/audio/hardware_opus_decoder_manager.h" @@ -18,17 +22,38 @@ namespace Service::Audio { void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); + // Main audio services server_manager->RegisterNamedService("audctl", std::make_shared(system)); server_manager->RegisterNamedService("audin:u", std::make_shared(system)); server_manager->RegisterNamedService("audout:u", std::make_shared(system)); - server_manager->RegisterNamedService( - "audrec:a", std::make_shared(system)); - server_manager->RegisterNamedService("audrec:u", - std::make_shared(system)); - server_manager->RegisterNamedService("audren:u", - std::make_shared(system)); - server_manager->RegisterNamedService("hwopus", - std::make_shared(system)); + server_manager->RegisterNamedService("audren:u", std::make_shared(system)); + server_manager->RegisterNamedService("hwopus", std::make_shared(system)); + + // Final output recorder services + server_manager->RegisterNamedService("audrec:a", std::make_shared(system)); + server_manager->RegisterNamedService("audrec:u", std::make_shared(system)); + + // Applet versions of audio services + server_manager->RegisterNamedService("audout:a", std::make_shared(system)); + server_manager->RegisterNamedService("audin:a", std::make_shared(system)); + server_manager->RegisterNamedService("audren:a", std::make_shared(system)); + + // Device suspend/resume services + server_manager->RegisterNamedService("audout:d", std::make_shared(system, "audout:d")); + server_manager->RegisterNamedService("audin:d", std::make_shared(system, "audin:d")); + server_manager->RegisterNamedService("audrec:d", std::make_shared(system, "audrec:d")); + server_manager->RegisterNamedService("audren:d", std::make_shared(system, "audren:d")); + + // Codec controller service + server_manager->RegisterNamedService("codecctl", std::make_shared(system)); + + // Debug service + server_manager->RegisterNamedService("auddebug", std::make_shared(system)); + + // System-level audio services + server_manager->RegisterNamedService("aud:a", std::make_shared(system)); // System version of audctl + server_manager->RegisterNamedService("aud:d", std::make_shared(system, "aud:d")); // System device service + ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp index 7a51d1023..2ff2a4bd0 100644 --- a/src/core/hle/service/audio/audio_controller.cpp +++ b/src/core/hle/service/audio/audio_controller.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/logging/log.h" @@ -14,60 +15,60 @@ IAudioController::IAudioController(Core::System& system_) : ServiceFramework{system_, "audctl"}, service_context{system, "audctl"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "GetTargetVolume"}, - {1, nullptr, "SetTargetVolume"}, + {0, D<&IAudioController::GetTargetVolume>, "GetTargetVolume"}, + {1, D<&IAudioController::SetTargetVolume>, "SetTargetVolume"}, {2, D<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"}, {3, D<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"}, - {4, nullptr, "IsTargetMute"}, - {5, nullptr, "SetTargetMute"}, - {6, nullptr, "IsTargetConnected"}, - {7, nullptr, "SetDefaultTarget"}, - {8, nullptr, "GetDefaultTarget"}, + {4, D<&IAudioController::IsTargetMute>, "IsTargetMute"}, + {5, D<&IAudioController::SetTargetMute>, "SetTargetMute"}, + {6, D<&IAudioController::IsTargetConnected>, "IsTargetConnected"}, + {7, D<&IAudioController::SetDefaultTarget>, "SetDefaultTarget"}, + {8, D<&IAudioController::GetDefaultTarget>, "GetDefaultTarget"}, {9, D<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"}, {10, D<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"}, - {11, nullptr, "SetForceMutePolicy"}, + {11, D<&IAudioController::SetForceMutePolicy>, "SetForceMutePolicy"}, {12, D<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"}, {13, D<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"}, {14, D<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"}, - {15, nullptr, "SetOutputTarget"}, - {16, nullptr, "SetInputTargetForceEnabled"}, + {15, D<&IAudioController::SetOutputTarget>, "SetOutputTarget"}, + {16, D<&IAudioController::SetInputTargetForceEnabled>, "SetInputTargetForceEnabled"}, {17, D<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"}, {18, D<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"}, - {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, - {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, - {21, nullptr, "GetAudioOutputTargetForPlayReport"}, + {19, D<&IAudioController::AcquireAudioVolumeUpdateEventForPlayReport>, "AcquireAudioVolumeUpdateEventForPlayReport"}, + {20, D<&IAudioController::AcquireAudioOutputDeviceUpdateEventForPlayReport>, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, + {21, D<&IAudioController::GetAudioOutputTargetForPlayReport>, "GetAudioOutputTargetForPlayReport"}, {22, D<&IAudioController::NotifyHeadphoneVolumeWarningDisplayedEvent>, "NotifyHeadphoneVolumeWarningDisplayedEvent"}, - {23, nullptr, "SetSystemOutputMasterVolume"}, - {24, nullptr, "GetSystemOutputMasterVolume"}, - {25, nullptr, "GetAudioVolumeDataForPlayReport"}, - {26, nullptr, "UpdateHeadphoneSettings"}, - {27, nullptr, "SetVolumeMappingTableForDev"}, - {28, nullptr, "GetAudioOutputChannelCountForPlayReport"}, - {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, + {23, D<&IAudioController::SetSystemOutputMasterVolume>, "SetSystemOutputMasterVolume"}, + {24, D<&IAudioController::GetSystemOutputMasterVolume>, "GetSystemOutputMasterVolume"}, + {25, D<&IAudioController::GetAudioVolumeDataForPlayReport>, "GetAudioVolumeDataForPlayReport"}, + {26, D<&IAudioController::UpdateHeadphoneSettings>, "UpdateHeadphoneSettings"}, + {27, D<&IAudioController::SetVolumeMappingTableForDev>, "SetVolumeMappingTableForDev"}, + {28, D<&IAudioController::GetAudioOutputChannelCountForPlayReport>, "GetAudioOutputChannelCountForPlayReport"}, + {29, D<&IAudioController::BindAudioOutputChannelCountUpdateEventForPlayReport>, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, {30, D<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"}, {31, D<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"}, - {32, nullptr, "GetActiveOutputTarget"}, - {33, nullptr, "GetTargetDeviceInfo"}, + {32, D<&IAudioController::GetActiveOutputTarget>, "GetActiveOutputTarget"}, + {33, D<&IAudioController::GetTargetDeviceInfo>, "GetTargetDeviceInfo"}, {34, D<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"}, - {35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, - {36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, - {37, nullptr, "SetHearingProtectionSafeguardEnabled"}, - {38, nullptr, "IsHearingProtectionSafeguardEnabled"}, - {39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"}, - {40, nullptr, "GetSystemInformationForDebug"}, - {41, nullptr, "SetVolumeButtonLongPressTime"}, - {42, nullptr, "SetNativeVolumeForDebug"}, - {10000, nullptr, "NotifyAudioOutputTargetForPlayReport"}, - {10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"}, - {10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"}, - {10100, nullptr, "GetAudioVolumeDataForPlayReport"}, - {10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"}, - {10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"}, - {10103, nullptr, "GetAudioOutputTargetForPlayReport"}, - {10104, nullptr, "GetAudioOutputChannelCountForPlayReport"}, - {10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, - {10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"}, - {50000, nullptr, "SetAnalogInputBoostGainForPrototyping"}, + {35, D<&IAudioController::SetHearingProtectionSafeguardTimerRemainingTimeForDebug>, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, + {36, D<&IAudioController::GetHearingProtectionSafeguardTimerRemainingTimeForDebug>, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"}, + {37, D<&IAudioController::SetHearingProtectionSafeguardEnabled>, "SetHearingProtectionSafeguardEnabled"}, + {38, D<&IAudioController::IsHearingProtectionSafeguardEnabled>, "IsHearingProtectionSafeguardEnabled"}, + {39, D<&IAudioController::IsHearingProtectionSafeguardMonitoringOutputForDebug>, "IsHearingProtectionSafeguardMonitoringOutputForDebug"}, + {40, D<&IAudioController::GetSystemInformationForDebug>, "GetSystemInformationForDebug"}, + {41, D<&IAudioController::SetVolumeButtonLongPressTime>, "SetVolumeButtonLongPressTime"}, + {42, D<&IAudioController::SetNativeVolumeForDebug>, "SetNativeVolumeForDebug"}, + {10000, D<&IAudioController::NotifyAudioOutputTargetForPlayReport>, "NotifyAudioOutputTargetForPlayReport"}, + {10001, D<&IAudioController::NotifyAudioOutputChannelCountForPlayReport>, "NotifyAudioOutputChannelCountForPlayReport"}, + {10002, D<&IAudioController::NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport>, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"}, + {10100, D<&IAudioController::GetAudioVolumeDataForPlayReport>, "GetAudioVolumeDataForPlayReport"}, + {10101, D<&IAudioController::BindAudioVolumeUpdateEventForPlayReport>, "BindAudioVolumeUpdateEventForPlayReport"}, + {10102, D<&IAudioController::BindAudioOutputTargetUpdateEventForPlayReport>, "BindAudioOutputTargetUpdateEventForPlayReport"}, + {10103, D<&IAudioController::GetAudioOutputTargetForPlayReport>, "GetAudioOutputTargetForPlayReport"}, + {10104, D<&IAudioController::GetAudioOutputChannelCountForPlayReport>, "GetAudioOutputChannelCountForPlayReport"}, + {10105, D<&IAudioController::BindAudioOutputChannelCountUpdateEventForPlayReport>, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, + {10106, D<&IAudioController::GetDefaultAudioOutputTargetForPlayReport>, "GetDefaultAudioOutputTargetForPlayReport"}, + {50000, D<&IAudioController::SetAnalogInputBoostGainForPrototyping>, "SetAnalogInputBoostGainForPrototyping"}, }; // clang-format on @@ -176,4 +177,208 @@ Result IAudioController::AcquireTargetNotification( R_SUCCEED(); } +Result IAudioController::GetTargetVolume(Out out_target_volume) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_target_volume = 10; + R_SUCCEED(); +} + +Result IAudioController::SetTargetVolume(s32 target_volume) { + LOG_WARNING(Audio, "(STUBBED) called, target_volume={}", target_volume); + R_SUCCEED(); +} + +Result IAudioController::IsTargetMute(Out out_is_target_mute) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_is_target_mute = false; + R_SUCCEED(); +} + +Result IAudioController::SetTargetMute(bool is_target_mute) { + LOG_WARNING(Audio, "(STUBBED) called, is_target_mute={}", is_target_mute); + R_SUCCEED(); +} + +Result IAudioController::IsTargetConnected(Out out_is_target_connected) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_is_target_connected = true; + R_SUCCEED(); +} + +Result IAudioController::SetDefaultTarget(u32 target) { + LOG_WARNING(Audio, "(STUBBED) called, target={}", target); + R_SUCCEED(); +} + +Result IAudioController::GetDefaultTarget(Out out_target) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_target = 0; + R_SUCCEED(); +} + +Result IAudioController::SetForceMutePolicy(ForceMutePolicy force_mute_policy) { + LOG_WARNING(Audio, "(STUBBED) called, force_mute_policy={}", static_cast(force_mute_policy)); + R_SUCCEED(); +} + +Result IAudioController::SetOutputTarget(u32 target) { + LOG_WARNING(Audio, "(STUBBED) called, target={}", target); + R_SUCCEED(); +} + +Result IAudioController::SetInputTargetForceEnabled(bool is_force_enabled) { + LOG_WARNING(Audio, "(STUBBED) called, is_force_enabled={}", is_force_enabled); + R_SUCCEED(); +} + +Result IAudioController::AcquireAudioVolumeUpdateEventForPlayReport(OutCopyHandle out_event) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_event = ¬ification_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IAudioController::AcquireAudioOutputDeviceUpdateEventForPlayReport(OutCopyHandle out_event) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_event = ¬ification_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IAudioController::GetAudioOutputTargetForPlayReport(Out out_target) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_target = 0; + R_SUCCEED(); +} + +Result IAudioController::SetSystemOutputMasterVolume(f32 volume) { + LOG_INFO(Audio, "called, volume={}", volume); + R_SUCCEED(); +} + +Result IAudioController::GetSystemOutputMasterVolume(Out out_volume) { + LOG_INFO(Audio, "called"); + *out_volume = 1.0f; + R_SUCCEED(); +} + +Result IAudioController::GetAudioVolumeDataForPlayReport(Out out_volume_data) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_volume_data = 0; + R_SUCCEED(); +} + +Result IAudioController::UpdateHeadphoneSettings() { + LOG_WARNING(Audio, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IAudioController::SetVolumeMappingTableForDev(InLargeData volume_mapping_table) { + LOG_WARNING(Audio, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IAudioController::GetAudioOutputChannelCountForPlayReport(Out out_channel_count) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_channel_count = 2; + R_SUCCEED(); +} + +Result IAudioController::BindAudioOutputChannelCountUpdateEventForPlayReport(OutCopyHandle out_event) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_event = ¬ification_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IAudioController::GetActiveOutputTarget(Out out_target) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_target = 0; + R_SUCCEED(); +} + +Result IAudioController::GetTargetDeviceInfo(Out out_device_info, u32 target) { + LOG_WARNING(Audio, "(STUBBED) called, target={}", target); + *out_device_info = 0; + R_SUCCEED(); +} + +Result IAudioController::SetHearingProtectionSafeguardTimerRemainingTimeForDebug(u64 remaining_time) { + LOG_WARNING(Audio, "(STUBBED) called, remaining_time={}", remaining_time); + R_SUCCEED(); +} + +Result IAudioController::GetHearingProtectionSafeguardTimerRemainingTimeForDebug(Out out_remaining_time) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_remaining_time = 0; + R_SUCCEED(); +} + +Result IAudioController::SetHearingProtectionSafeguardEnabled(bool is_enabled) { + LOG_WARNING(Audio, "(STUBBED) called, is_enabled={}", is_enabled); + R_SUCCEED(); +} + +Result IAudioController::IsHearingProtectionSafeguardEnabled(Out out_is_enabled) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_is_enabled = false; + R_SUCCEED(); +} + +Result IAudioController::IsHearingProtectionSafeguardMonitoringOutputForDebug(Out out_is_monitoring) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_is_monitoring = false; + R_SUCCEED(); +} + +Result IAudioController::GetSystemInformationForDebug(OutLargeData out_info) { + LOG_WARNING(Audio, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IAudioController::SetVolumeButtonLongPressTime(u64 long_press_time) { + LOG_WARNING(Audio, "(STUBBED) called, long_press_time={}", long_press_time); + R_SUCCEED(); +} + +Result IAudioController::SetNativeVolumeForDebug(f32 native_volume) { + LOG_WARNING(Audio, "(STUBBED) called, native_volume={}", native_volume); + R_SUCCEED(); +} + +Result IAudioController::NotifyAudioOutputTargetForPlayReport(u32 target) { + LOG_WARNING(Audio, "(STUBBED) called, target={}", target); + R_SUCCEED(); +} + +Result IAudioController::NotifyAudioOutputChannelCountForPlayReport(u32 channel_count) { + LOG_WARNING(Audio, "(STUBBED) called, channel_count={}", channel_count); + R_SUCCEED(); +} + +Result IAudioController::NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport() { + LOG_WARNING(Audio, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IAudioController::BindAudioVolumeUpdateEventForPlayReport(OutCopyHandle out_event) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_event = ¬ification_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IAudioController::BindAudioOutputTargetUpdateEventForPlayReport(OutCopyHandle out_event) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_event = ¬ification_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result IAudioController::GetDefaultAudioOutputTargetForPlayReport(Out out_target) { + LOG_WARNING(Audio, "(STUBBED) called"); + *out_target = 0; + R_SUCCEED(); +} + +Result IAudioController::SetAnalogInputBoostGainForPrototyping(f32 gain) { + LOG_WARNING(Audio, "(STUBBED) called, gain={}", gain); + R_SUCCEED(); +} + } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_controller.h b/src/core/hle/service/audio/audio_controller.h index d37c4843e..198cbcc7c 100644 --- a/src/core/hle/service/audio/audio_controller.h +++ b/src/core/hle/service/audio/audio_controller.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -33,22 +34,59 @@ private: HighPower, }; + Result GetTargetVolume(Out out_target_volume); + Result SetTargetVolume(s32 target_volume); Result GetTargetVolumeMin(Out out_target_min_volume); Result GetTargetVolumeMax(Out out_target_max_volume); + Result IsTargetMute(Out out_is_target_mute); + Result SetTargetMute(bool is_target_mute); + Result IsTargetConnected(Out out_is_target_connected); + Result SetDefaultTarget(u32 target); + Result GetDefaultTarget(Out out_target); Result GetAudioOutputMode(Out out_output_mode, Set::AudioOutputModeTarget target); Result SetAudioOutputMode(Set::AudioOutputModeTarget target, Set::AudioOutputMode output_mode); + Result SetForceMutePolicy(ForceMutePolicy force_mute_policy); Result GetForceMutePolicy(Out out_mute_policy); Result GetOutputModeSetting(Out out_output_mode, Set::AudioOutputModeTarget target); Result SetOutputModeSetting(Set::AudioOutputModeTarget target, Set::AudioOutputMode output_mode); + Result SetOutputTarget(u32 target); + Result SetInputTargetForceEnabled(bool is_force_enabled); Result SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode); Result GetHeadphoneOutputLevelMode(Out out_output_level_mode); + Result AcquireAudioVolumeUpdateEventForPlayReport(OutCopyHandle out_event); + Result AcquireAudioOutputDeviceUpdateEventForPlayReport(OutCopyHandle out_event); + Result GetAudioOutputTargetForPlayReport(Out out_target); Result NotifyHeadphoneVolumeWarningDisplayedEvent(); + Result SetSystemOutputMasterVolume(f32 volume); + Result GetSystemOutputMasterVolume(Out out_volume); + Result GetAudioVolumeDataForPlayReport(Out out_volume_data); + Result UpdateHeadphoneSettings(); + Result SetVolumeMappingTableForDev(InLargeData volume_mapping_table); + Result GetAudioOutputChannelCountForPlayReport(Out out_channel_count); + Result BindAudioOutputChannelCountUpdateEventForPlayReport(OutCopyHandle out_event); Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled); Result IsSpeakerAutoMuteEnabled(Out out_is_speaker_auto_mute_enabled); + Result GetActiveOutputTarget(Out out_target); + Result GetTargetDeviceInfo(Out out_device_info, u32 target); Result AcquireTargetNotification(OutCopyHandle out_notification_event); + Result SetHearingProtectionSafeguardTimerRemainingTimeForDebug(u64 remaining_time); + Result GetHearingProtectionSafeguardTimerRemainingTimeForDebug(Out out_remaining_time); + Result SetHearingProtectionSafeguardEnabled(bool is_enabled); + Result IsHearingProtectionSafeguardEnabled(Out out_is_enabled); + Result IsHearingProtectionSafeguardMonitoringOutputForDebug(Out out_is_monitoring); + Result GetSystemInformationForDebug(OutLargeData out_info); + Result SetVolumeButtonLongPressTime(u64 long_press_time); + Result SetNativeVolumeForDebug(f32 native_volume); + Result NotifyAudioOutputTargetForPlayReport(u32 target); + Result NotifyAudioOutputChannelCountForPlayReport(u32 channel_count); + Result NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport(); + Result BindAudioVolumeUpdateEventForPlayReport(OutCopyHandle out_event); + Result BindAudioOutputTargetUpdateEventForPlayReport(OutCopyHandle out_event); + Result GetDefaultAudioOutputTargetForPlayReport(Out out_target); + Result SetAnalogInputBoostGainForPrototyping(f32 gain); KernelHelpers::ServiceContext service_context; diff --git a/src/core/hle/service/audio/audio_debug.cpp b/src/core/hle/service/audio/audio_debug.cpp new file mode 100644 index 000000000..65efe0b2b --- /dev/null +++ b/src/core/hle/service/audio/audio_debug.cpp @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/audio/audio_debug.h" + +namespace Service::Audio { + +IAudioDebugManager::IAudioDebugManager(Core::System& system_) + : ServiceFramework{system_, "auddebug"} { + // TODO: Implement debug functions +} + +IAudioDebugManager::~IAudioDebugManager() = default; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_debug.h b/src/core/hle/service/audio/audio_debug.h new file mode 100644 index 000000000..870d40f9b --- /dev/null +++ b/src/core/hle/service/audio/audio_debug.h @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class IAudioDebugManager final : public ServiceFramework { +public: + explicit IAudioDebugManager(Core::System& system_); + ~IAudioDebugManager() override; + +private: + // TODO: Implement debug functions +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_device.cpp b/src/core/hle/service/audio/audio_device.cpp index 438f3cccd..735075d19 100644 --- a/src/core/hle/service/audio/audio_device.cpp +++ b/src/core/hle/service/audio/audio_device.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "audio_core/audio_core.h" @@ -22,12 +23,13 @@ IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u {4, D<&IAudioDevice::QueryAudioDeviceSystemEvent>, "QueryAudioDeviceSystemEvent"}, {5, D<&IAudioDevice::GetActiveChannelCount>, "GetActiveChannelCount"}, {6, D<&IAudioDevice::ListAudioDeviceNameAuto>, "ListAudioDeviceNameAuto"}, - {7, D<&IAudioDevice::SetAudioDeviceOutputVolumeAuto>, "SetAudioDeviceOutputVolumeAuto"}, - {8, D<&IAudioDevice::GetAudioDeviceOutputVolumeAuto>, "GetAudioDeviceOutputVolumeAuto"}, + {7, D<&IAudioDevice::GetAudioSystemMasterVolumeSetting>, "GetAudioSystemMasterVolumeSetting"}, + {8, D<&IAudioDevice::SetAudioDeviceOutputVolumeAuto>, "SetAudioDeviceOutputVolumeAuto"}, + {9, D<&IAudioDevice::GetAudioDeviceOutputVolumeAuto>, "GetAudioDeviceOutputVolumeAuto"}, {10, D<&IAudioDevice::GetActiveAudioDeviceNameAuto>, "GetActiveAudioDeviceNameAuto"}, {11, D<&IAudioDevice::QueryAudioDeviceInputEvent>, "QueryAudioDeviceInputEvent"}, {12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"}, - {13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"}, + {13, D<&IAudioDevice::GetActiveAudioOutputDeviceName>, "GetActiveAudioOutputDeviceName"}, {14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"}, }; RegisterHandlers(functions); @@ -141,6 +143,17 @@ Result IAudioDevice::GetActiveChannelCount(Out out_active_channel_count) { R_SUCCEED(); } +Result IAudioDevice::GetAudioSystemMasterVolumeSetting(Out out_volume) { + LOG_DEBUG(Service_Audio, "(STUBBED) called"); + *out_volume = 1.0f; + R_SUCCEED(); +} + +Result IAudioDevice::GetActiveAudioOutputDeviceName( + OutArray out_name) { + R_RETURN(this->GetActiveAudioDeviceNameAuto(out_name)); +} + Result IAudioDevice::ListAudioOutputDeviceName( OutArray out_names, Out out_count) { *out_count = impl->ListAudioOutputDeviceName(out_names); diff --git a/src/core/hle/service/audio/audio_device.h b/src/core/hle/service/audio/audio_device.h index 752157272..8fd4f1269 100644 --- a/src/core/hle/service/audio/audio_device.h +++ b/src/core/hle/service/audio/audio_device.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -46,6 +47,9 @@ private: Result QueryAudioDeviceInputEvent(OutCopyHandle out_event); Result QueryAudioDeviceOutputEvent(OutCopyHandle out_event); Result GetActiveChannelCount(Out out_active_channel_count); + Result GetAudioSystemMasterVolumeSetting(Out out_volume); + Result GetActiveAudioOutputDeviceName( + OutArray out_name); Result ListAudioOutputDeviceName( OutArray out_names, Out out_count); diff --git a/src/core/hle/service/audio/audio_device_service.cpp b/src/core/hle/service/audio/audio_device_service.cpp new file mode 100644 index 000000000..0af5d67fb --- /dev/null +++ b/src/core/hle/service/audio/audio_device_service.cpp @@ -0,0 +1,34 @@ +// 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_device_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::Audio { + +IAudioDeviceService::IAudioDeviceService(Core::System& system_, const char* name) + : ServiceFramework{system_, name} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&IAudioDeviceService::RequestSuspend>, "RequestSuspend"}, + {1, D<&IAudioDeviceService::RequestResume>, "RequestResume"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IAudioDeviceService::~IAudioDeviceService() = default; + +Result IAudioDeviceService::RequestSuspend(u64 process_id) { + LOG_WARNING(Service_Audio, "(STUBBED) called, process_id={:#x}", process_id); + R_SUCCEED(); +} + +Result IAudioDeviceService::RequestResume(u64 process_id) { + LOG_WARNING(Service_Audio, "(STUBBED) called, process_id={:#x}", process_id); + R_SUCCEED(); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_device_service.h b/src/core/hle/service/audio/audio_device_service.h new file mode 100644 index 000000000..a85efd273 --- /dev/null +++ b/src/core/hle/service/audio/audio_device_service.h @@ -0,0 +1,21 @@ +// 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 Service::Audio { + +class IAudioDeviceService final : public ServiceFramework { +public: + explicit IAudioDeviceService(Core::System& system_, const char* name); + ~IAudioDeviceService() override; + +private: + Result RequestSuspend(u64 process_id); + Result RequestResume(u64 process_id); +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/codecctl.cpp b/src/core/hle/service/audio/codecctl.cpp new file mode 100644 index 000000000..c873f192a --- /dev/null +++ b/src/core/hle/service/audio/codecctl.cpp @@ -0,0 +1,110 @@ +// 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/codecctl.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::Audio { + +ICodecController::ICodecController(Core::System& system_) + : ServiceFramework{system_, "codecctl"}, service_context{system_, "codecctl"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&ICodecController::Initialize>, "Initialize"}, + {1, D<&ICodecController::Finalize>, "Finalize"}, + {2, D<&ICodecController::Sleep>, "Sleep"}, + {3, D<&ICodecController::Wake>, "Wake"}, + {4, D<&ICodecController::SetVolume>, "SetVolume"}, + {5, D<&ICodecController::GetVolumeMax>, "GetVolumeMax"}, + {6, D<&ICodecController::GetVolumeMin>, "GetVolumeMin"}, + {7, D<&ICodecController::SetActiveTarget>, "SetActiveTarget"}, + {8, D<&ICodecController::GetActiveTarget>, "GetActiveTarget"}, + {9, D<&ICodecController::BindHeadphoneMicJackInterrupt>, "BindHeadphoneMicJackInterrupt"}, + {10, D<&ICodecController::IsHeadphoneMicJackInserted>, "IsHeadphoneMicJackInserted"}, + {11, D<&ICodecController::ClearHeadphoneMicJackInterrupt>, "ClearHeadphoneMicJackInterrupt"}, + {12, D<&ICodecController::IsRequested>, "IsRequested"}, + }; + // clang-format on + + RegisterHandlers(functions); + + mic_jack_event = service_context.CreateEvent("CodecCtl:MicJackEvent"); +} + +ICodecController::~ICodecController() { + service_context.CloseEvent(mic_jack_event); +} + +Result ICodecController::Initialize() { + LOG_INFO(Service_Audio, "called"); + R_SUCCEED(); +} + +Result ICodecController::Finalize() { + LOG_INFO(Service_Audio, "called"); + R_SUCCEED(); +} + +Result ICodecController::Sleep() { + LOG_WARNING(Service_Audio, "(STUBBED) called"); + R_SUCCEED(); +} + +Result ICodecController::Wake() { + LOG_WARNING(Service_Audio, "(STUBBED) called"); + R_SUCCEED(); +} + +Result ICodecController::SetVolume(f32 volume) { + LOG_INFO(Service_Audio, "called, volume={}", volume); + R_SUCCEED(); +} + +Result ICodecController::GetVolumeMax(Out out_volume_max) { + LOG_INFO(Service_Audio, "called"); + *out_volume_max = 1.0f; + R_SUCCEED(); +} + +Result ICodecController::GetVolumeMin(Out out_volume_min) { + LOG_INFO(Service_Audio, "called"); + *out_volume_min = 0.0f; + R_SUCCEED(); +} + +Result ICodecController::SetActiveTarget(u32 target) { + LOG_INFO(Service_Audio, "called, target={}", target); + R_SUCCEED(); +} + +Result ICodecController::GetActiveTarget(Out out_target) { + LOG_INFO(Service_Audio, "called"); + *out_target = 0; + R_SUCCEED(); +} + +Result ICodecController::BindHeadphoneMicJackInterrupt(OutCopyHandle out_event) { + LOG_INFO(Service_Audio, "called"); + *out_event = &mic_jack_event->GetReadableEvent(); + R_SUCCEED(); +} + +Result ICodecController::IsHeadphoneMicJackInserted(Out out_is_inserted) { + LOG_WARNING(Service_Audio, "(STUBBED) called"); + *out_is_inserted = false; + R_SUCCEED(); +} + +Result ICodecController::ClearHeadphoneMicJackInterrupt() { + LOG_INFO(Service_Audio, "called"); + R_SUCCEED(); +} + +Result ICodecController::IsRequested(Out out_is_requested) { + LOG_WARNING(Service_Audio, "(STUBBED) called"); + *out_is_requested = false; + R_SUCCEED(); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/codecctl.h b/src/core/hle/service/audio/codecctl.h new file mode 100644 index 000000000..ddd7028f0 --- /dev/null +++ b/src/core/hle/service/audio/codecctl.h @@ -0,0 +1,40 @@ +// 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/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Kernel { +class KReadableEvent; +} + +namespace Service::Audio { + +class ICodecController final : public ServiceFramework { +public: + explicit ICodecController(Core::System& system_); + ~ICodecController() override; + +private: + Result Initialize(); + Result Finalize(); + Result Sleep(); + Result Wake(); + Result SetVolume(f32 volume); + Result GetVolumeMax(Out out_volume_max); + Result GetVolumeMin(Out out_volume_min); + Result SetActiveTarget(u32 target); + Result GetActiveTarget(Out out_target); + Result BindHeadphoneMicJackInterrupt(OutCopyHandle out_event); + Result IsHeadphoneMicJackInserted(Out out_is_inserted); + Result ClearHeadphoneMicJackInterrupt(); + Result IsRequested(Out out_is_requested); + + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* mic_jack_event; +}; + +} // namespace Service::Audio