audio_device.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "audio_core/audio_core.h"
  4. #include "common/string_util.h"
  5. #include "core/hle/service/audio/audio_device.h"
  6. #include "core/hle/service/cmif_serialization.h"
  7. namespace Service::Audio {
  8. using namespace AudioCore::Renderer;
  9. IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision,
  10. u32 device_num)
  11. : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"},
  12. impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)},
  13. event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} {
  14. static const FunctionInfo functions[] = {
  15. {0, D<&IAudioDevice::ListAudioDeviceName>, "ListAudioDeviceName"},
  16. {1, D<&IAudioDevice::SetAudioDeviceOutputVolume>, "SetAudioDeviceOutputVolume"},
  17. {2, D<&IAudioDevice::GetAudioDeviceOutputVolume>, "GetAudioDeviceOutputVolume"},
  18. {3, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioDeviceName"},
  19. {4, D<&IAudioDevice::QueryAudioDeviceSystemEvent>, "QueryAudioDeviceSystemEvent"},
  20. {5, D<&IAudioDevice::GetActiveChannelCount>, "GetActiveChannelCount"},
  21. {6, D<&IAudioDevice::ListAudioDeviceNameAuto>, "ListAudioDeviceNameAuto"},
  22. {7, D<&IAudioDevice::SetAudioDeviceOutputVolumeAuto>, "SetAudioDeviceOutputVolumeAuto"},
  23. {8, D<&IAudioDevice::GetAudioDeviceOutputVolumeAuto>, "GetAudioDeviceOutputVolumeAuto"},
  24. {10, D<&IAudioDevice::GetActiveAudioDeviceNameAuto>, "GetActiveAudioDeviceNameAuto"},
  25. {11, D<&IAudioDevice::QueryAudioDeviceInputEvent>, "QueryAudioDeviceInputEvent"},
  26. {12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"},
  27. {13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"},
  28. {14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"},
  29. };
  30. RegisterHandlers(functions);
  31. event->Signal();
  32. }
  33. IAudioDevice::~IAudioDevice() {
  34. service_context.CloseEvent(event);
  35. }
  36. Result IAudioDevice::ListAudioDeviceName(
  37. OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names, Out<s32> out_count) {
  38. R_RETURN(this->ListAudioDeviceNameAuto(out_names, out_count));
  39. }
  40. Result IAudioDevice::SetAudioDeviceOutputVolume(
  41. InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> name, f32 volume) {
  42. R_RETURN(this->SetAudioDeviceOutputVolumeAuto(name, volume));
  43. }
  44. Result IAudioDevice::GetAudioDeviceOutputVolume(
  45. Out<f32> out_volume, InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> name) {
  46. R_RETURN(this->GetAudioDeviceOutputVolumeAuto(out_volume, name));
  47. }
  48. Result IAudioDevice::GetActiveAudioDeviceName(
  49. OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_name) {
  50. R_RETURN(this->GetActiveAudioDeviceNameAuto(out_name));
  51. }
  52. Result IAudioDevice::ListAudioDeviceNameAuto(
  53. OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> out_names,
  54. Out<s32> out_count) {
  55. *out_count = impl->ListAudioDeviceName(out_names);
  56. std::string out{};
  57. for (s32 i = 0; i < *out_count; i++) {
  58. std::string a{};
  59. u32 j = 0;
  60. while (out_names[i].name[j] != '\0') {
  61. a += out_names[i].name[j];
  62. j++;
  63. }
  64. out += "\n\t" + a;
  65. }
  66. LOG_DEBUG(Service_Audio, "called.\nNames={}", out);
  67. R_SUCCEED();
  68. }
  69. Result IAudioDevice::SetAudioDeviceOutputVolumeAuto(
  70. InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> name, f32 volume) {
  71. R_UNLESS(!name.empty(), Audio::ResultInsufficientBuffer);
  72. const std::string device_name = Common::StringFromBuffer(name[0].name);
  73. LOG_DEBUG(Service_Audio, "called. name={}, volume={}", device_name, volume);
  74. if (device_name == "AudioTvOutput") {
  75. impl->SetDeviceVolumes(volume);
  76. }
  77. R_SUCCEED();
  78. }
  79. Result IAudioDevice::GetAudioDeviceOutputVolumeAuto(
  80. Out<f32> out_volume, InArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> name) {
  81. R_UNLESS(!name.empty(), Audio::ResultInsufficientBuffer);
  82. const std::string device_name = Common::StringFromBuffer(name[0].name);
  83. LOG_DEBUG(Service_Audio, "called. Name={}", device_name);
  84. *out_volume = 1.0f;
  85. if (device_name == "AudioTvOutput") {
  86. *out_volume = impl->GetDeviceVolume(device_name);
  87. }
  88. R_SUCCEED();
  89. }
  90. Result IAudioDevice::GetActiveAudioDeviceNameAuto(
  91. OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcAutoSelect> out_name) {
  92. R_UNLESS(!out_name.empty(), Audio::ResultInsufficientBuffer);
  93. out_name[0] = AudioDevice::AudioDeviceName("AudioTvOutput");
  94. LOG_DEBUG(Service_Audio, "(STUBBED) called");
  95. R_SUCCEED();
  96. }
  97. Result IAudioDevice::QueryAudioDeviceSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
  98. LOG_DEBUG(Service_Audio, "(STUBBED) called");
  99. event->Signal();
  100. *out_event = &event->GetReadableEvent();
  101. R_SUCCEED();
  102. }
  103. Result IAudioDevice::QueryAudioDeviceInputEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
  104. LOG_DEBUG(Service_Audio, "(STUBBED) called");
  105. *out_event = &event->GetReadableEvent();
  106. R_SUCCEED();
  107. }
  108. Result IAudioDevice::QueryAudioDeviceOutputEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
  109. LOG_DEBUG(Service_Audio, "called");
  110. *out_event = &event->GetReadableEvent();
  111. R_SUCCEED();
  112. }
  113. Result IAudioDevice::GetActiveChannelCount(Out<u32> out_active_channel_count) {
  114. *out_active_channel_count = system.AudioCore().GetOutputSink().GetSystemChannels();
  115. LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", *out_active_channel_count);
  116. R_SUCCEED();
  117. }
  118. Result IAudioDevice::ListAudioOutputDeviceName(
  119. OutArray<AudioDevice::AudioDeviceName, BufferAttr_HipcMapAlias> out_names, Out<s32> out_count) {
  120. *out_count = impl->ListAudioOutputDeviceName(out_names);
  121. std::string out{};
  122. for (s32 i = 0; i < *out_count; i++) {
  123. std::string a{};
  124. u32 j = 0;
  125. while (out_names[i].name[j] != '\0') {
  126. a += out_names[i].name[j];
  127. j++;
  128. }
  129. out += "\n\t" + a;
  130. }
  131. LOG_DEBUG(Service_Audio, "called.\nNames={}", out);
  132. R_SUCCEED();
  133. }
  134. } // namespace Service::Audio