Merge branch 'audio-add-new-functions-services' into 'master'

hle/service/audio: Implement missing audio services and functions

See merge request citron/rewrite!18
This commit is contained in:
Zephyron
2025-05-24 06:40:11 +00:00
12 changed files with 582 additions and 52 deletions

View File

@@ -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

View File

@@ -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<ServerManager>(system);
// Main audio services
server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system));
server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system));
server_manager->RegisterNamedService("audout:u", std::make_shared<IAudioOutManager>(system));
server_manager->RegisterNamedService(
"audrec:a", std::make_shared<IFinalOutputRecorderManagerForApplet>(system));
server_manager->RegisterNamedService("audrec:u",
std::make_shared<IFinalOutputRecorderManager>(system));
server_manager->RegisterNamedService("audren:u",
std::make_shared<IAudioRendererManager>(system));
server_manager->RegisterNamedService("hwopus",
std::make_shared<IHardwareOpusDecoderManager>(system));
server_manager->RegisterNamedService("audren:u", std::make_shared<IAudioRendererManager>(system));
server_manager->RegisterNamedService("hwopus", std::make_shared<IHardwareOpusDecoderManager>(system));
// Final output recorder services
server_manager->RegisterNamedService("audrec:a", std::make_shared<IFinalOutputRecorderManagerForApplet>(system));
server_manager->RegisterNamedService("audrec:u", std::make_shared<IFinalOutputRecorderManager>(system));
// Applet versions of audio services
server_manager->RegisterNamedService("audout:a", std::make_shared<IAudioOutManager>(system));
server_manager->RegisterNamedService("audin:a", std::make_shared<IAudioInManager>(system));
server_manager->RegisterNamedService("audren:a", std::make_shared<IAudioRendererManager>(system));
// Device suspend/resume services
server_manager->RegisterNamedService("audout:d", std::make_shared<IAudioDeviceService>(system, "audout:d"));
server_manager->RegisterNamedService("audin:d", std::make_shared<IAudioDeviceService>(system, "audin:d"));
server_manager->RegisterNamedService("audrec:d", std::make_shared<IAudioDeviceService>(system, "audrec:d"));
server_manager->RegisterNamedService("audren:d", std::make_shared<IAudioDeviceService>(system, "audren:d"));
// Codec controller service
server_manager->RegisterNamedService("codecctl", std::make_shared<ICodecController>(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
ServerManager::RunServer(std::move(server_manager));
}

View File

@@ -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<s32> 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<bool> 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<bool> 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<u32> 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<u32>(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<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_event = &notification_event->GetReadableEvent();
R_SUCCEED();
}
Result IAudioController::AcquireAudioOutputDeviceUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_event = &notification_event->GetReadableEvent();
R_SUCCEED();
}
Result IAudioController::GetAudioOutputTargetForPlayReport(Out<u32> 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<f32> out_volume) {
LOG_INFO(Audio, "called");
*out_volume = 1.0f;
R_SUCCEED();
}
Result IAudioController::GetAudioVolumeDataForPlayReport(Out<u32> 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<u32, BufferAttr_HipcMapAlias> volume_mapping_table) {
LOG_WARNING(Audio, "(STUBBED) called");
R_SUCCEED();
}
Result IAudioController::GetAudioOutputChannelCountForPlayReport(Out<u32> out_channel_count) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_channel_count = 2;
R_SUCCEED();
}
Result IAudioController::BindAudioOutputChannelCountUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_event = &notification_event->GetReadableEvent();
R_SUCCEED();
}
Result IAudioController::GetActiveOutputTarget(Out<u32> out_target) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_target = 0;
R_SUCCEED();
}
Result IAudioController::GetTargetDeviceInfo(Out<u32> 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<u64> 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<bool> out_is_enabled) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_is_enabled = false;
R_SUCCEED();
}
Result IAudioController::IsHearingProtectionSafeguardMonitoringOutputForDebug(Out<bool> out_is_monitoring) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_is_monitoring = false;
R_SUCCEED();
}
Result IAudioController::GetSystemInformationForDebug(OutLargeData<u8, BufferAttr_HipcMapAlias> 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<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_event = &notification_event->GetReadableEvent();
R_SUCCEED();
}
Result IAudioController::BindAudioOutputTargetUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Audio, "(STUBBED) called");
*out_event = &notification_event->GetReadableEvent();
R_SUCCEED();
}
Result IAudioController::GetDefaultAudioOutputTargetForPlayReport(Out<u32> 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

View File

@@ -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<s32> out_target_volume);
Result SetTargetVolume(s32 target_volume);
Result GetTargetVolumeMin(Out<s32> out_target_min_volume);
Result GetTargetVolumeMax(Out<s32> out_target_max_volume);
Result IsTargetMute(Out<bool> out_is_target_mute);
Result SetTargetMute(bool is_target_mute);
Result IsTargetConnected(Out<bool> out_is_target_connected);
Result SetDefaultTarget(u32 target);
Result GetDefaultTarget(Out<u32> out_target);
Result GetAudioOutputMode(Out<Set::AudioOutputMode> out_output_mode,
Set::AudioOutputModeTarget target);
Result SetAudioOutputMode(Set::AudioOutputModeTarget target, Set::AudioOutputMode output_mode);
Result SetForceMutePolicy(ForceMutePolicy force_mute_policy);
Result GetForceMutePolicy(Out<ForceMutePolicy> out_mute_policy);
Result GetOutputModeSetting(Out<Set::AudioOutputMode> 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<HeadphoneOutputLevelMode> out_output_level_mode);
Result AcquireAudioVolumeUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result AcquireAudioOutputDeviceUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetAudioOutputTargetForPlayReport(Out<u32> out_target);
Result NotifyHeadphoneVolumeWarningDisplayedEvent();
Result SetSystemOutputMasterVolume(f32 volume);
Result GetSystemOutputMasterVolume(Out<f32> out_volume);
Result GetAudioVolumeDataForPlayReport(Out<u32> out_volume_data);
Result UpdateHeadphoneSettings();
Result SetVolumeMappingTableForDev(InLargeData<u32, BufferAttr_HipcMapAlias> volume_mapping_table);
Result GetAudioOutputChannelCountForPlayReport(Out<u32> out_channel_count);
Result BindAudioOutputChannelCountUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled);
Result IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled);
Result GetActiveOutputTarget(Out<u32> out_target);
Result GetTargetDeviceInfo(Out<u32> out_device_info, u32 target);
Result AcquireTargetNotification(OutCopyHandle<Kernel::KReadableEvent> out_notification_event);
Result SetHearingProtectionSafeguardTimerRemainingTimeForDebug(u64 remaining_time);
Result GetHearingProtectionSafeguardTimerRemainingTimeForDebug(Out<u64> out_remaining_time);
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 SetVolumeButtonLongPressTime(u64 long_press_time);
Result SetNativeVolumeForDebug(f32 native_volume);
Result NotifyAudioOutputTargetForPlayReport(u32 target);
Result NotifyAudioOutputChannelCountForPlayReport(u32 channel_count);
Result NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport();
Result BindAudioVolumeUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result BindAudioOutputTargetUpdateEventForPlayReport(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetDefaultAudioOutputTargetForPlayReport(Out<u32> out_target);
Result SetAnalogInputBoostGainForPrototyping(f32 gain);
KernelHelpers::ServiceContext service_context;

View File

@@ -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

View File

@@ -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<IAudioDebugManager> {
public:
explicit IAudioDebugManager(Core::System& system_);
~IAudioDebugManager() override;
private:
// TODO: Implement debug functions
};
} // namespace Service::Audio

View File

@@ -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<u32> out_active_channel_count) {
R_SUCCEED();
}
Result IAudioDevice::GetAudioSystemMasterVolumeSetting(Out<f32> out_volume) {
LOG_DEBUG(Service_Audio, "(STUBBED) called");
*out_volume = 1.0f;
R_SUCCEED();
}
Result IAudioDevice::GetActiveAudioOutputDeviceName(
OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_name) {
R_RETURN(this->GetActiveAudioDeviceNameAuto(out_name));
}
Result IAudioDevice::ListAudioOutputDeviceName(
OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names, Out<s32> out_count) {
*out_count = impl->ListAudioOutputDeviceName(out_names);

View File

@@ -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<Kernel::KReadableEvent> out_event);
Result QueryAudioDeviceOutputEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetActiveChannelCount(Out<u32> out_active_channel_count);
Result GetAudioSystemMasterVolumeSetting(Out<f32> out_volume);
Result GetActiveAudioOutputDeviceName(
OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_name);
Result ListAudioOutputDeviceName(
OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names,
Out<s32> out_count);

View File

@@ -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

View File

@@ -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<IAudioDeviceService> {
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

View File

@@ -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<f32> out_volume_max) {
LOG_INFO(Service_Audio, "called");
*out_volume_max = 1.0f;
R_SUCCEED();
}
Result ICodecController::GetVolumeMin(Out<f32> 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<u32> out_target) {
LOG_INFO(Service_Audio, "called");
*out_target = 0;
R_SUCCEED();
}
Result ICodecController::BindHeadphoneMicJackInterrupt(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_INFO(Service_Audio, "called");
*out_event = &mic_jack_event->GetReadableEvent();
R_SUCCEED();
}
Result ICodecController::IsHeadphoneMicJackInserted(Out<bool> 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<bool> out_is_requested) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
*out_is_requested = false;
R_SUCCEED();
}
} // namespace Service::Audio

View File

@@ -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<ICodecController> {
public:
explicit ICodecController(Core::System& system_);
~ICodecController() override;
private:
Result Initialize();
Result Finalize();
Result Sleep();
Result Wake();
Result SetVolume(f32 volume);
Result GetVolumeMax(Out<f32> out_volume_max);
Result GetVolumeMin(Out<f32> out_volume_min);
Result SetActiveTarget(u32 target);
Result GetActiveTarget(Out<u32> out_target);
Result BindHeadphoneMicJackInterrupt(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsHeadphoneMicJackInserted(Out<bool> out_is_inserted);
Result ClearHeadphoneMicJackInterrupt();
Result IsRequested(Out<bool> out_is_requested);
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* mic_jack_event;
};
} // namespace Service::Audio