audio_in.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "core/hle/service/audio/audio_in.h"
  4. #include "core/hle/service/cmif_serialization.h"
  5. #include "core/hle/service/ipc_helpers.h"
  6. namespace Service::Audio {
  7. using namespace AudioCore::AudioIn;
  8. IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
  9. const std::string& device_name, const AudioInParameter& in_params,
  10. Kernel::KProcess* handle, u64 applet_resource_user_id)
  11. : ServiceFramework{system_, "IAudioIn"}, process{handle}, service_context{system_, "IAudioIn"},
  12. event{service_context.CreateEvent("AudioInEvent")}, impl{std::make_shared<In>(system_,
  13. manager, event,
  14. session_id)} {
  15. // clang-format off
  16. static const FunctionInfo functions[] = {
  17. {0, D<&IAudioIn::GetAudioInState>, "GetAudioInState"},
  18. {1, D<&IAudioIn::Start>, "Start"},
  19. {2, D<&IAudioIn::Stop>, "Stop"},
  20. {3, D<&IAudioIn::AppendAudioInBuffer>, "AppendAudioInBuffer"},
  21. {4, D<&IAudioIn::RegisterBufferEvent>, "RegisterBufferEvent"},
  22. {5, D<&IAudioIn::GetReleasedAudioInBuffers>, "GetReleasedAudioInBuffers"},
  23. {6, D<&IAudioIn::ContainsAudioInBuffer>, "ContainsAudioInBuffer"},
  24. {7, D<&IAudioIn::AppendAudioInBuffer>, "AppendUacInBuffer"},
  25. {8, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendAudioInBufferAuto"},
  26. {9, D<&IAudioIn::GetReleasedAudioInBuffersAuto>, "GetReleasedAudioInBuffersAuto"},
  27. {10, D<&IAudioIn::AppendAudioInBufferAuto>, "AppendUacInBufferAuto"},
  28. {11, D<&IAudioIn::GetAudioInBufferCount>, "GetAudioInBufferCount"},
  29. {12, D<&IAudioIn::SetDeviceGain>, "SetDeviceGain"},
  30. {13, D<&IAudioIn::GetDeviceGain>, "GetDeviceGain"},
  31. {14, D<&IAudioIn::FlushAudioInBuffers>, "FlushAudioInBuffers"},
  32. };
  33. // clang-format on
  34. RegisterHandlers(functions);
  35. process->Open();
  36. if (impl->GetSystem()
  37. .Initialize(device_name, in_params, handle, applet_resource_user_id)
  38. .IsError()) {
  39. LOG_ERROR(Service_Audio, "Failed to initialize the AudioIn System!");
  40. }
  41. }
  42. IAudioIn::~IAudioIn() {
  43. impl->Free();
  44. service_context.CloseEvent(event);
  45. process->Close();
  46. }
  47. Result IAudioIn::GetAudioInState(Out<u32> out_state) {
  48. *out_state = static_cast<u32>(impl->GetState());
  49. LOG_DEBUG(Service_Audio, "called. state={}", *out_state);
  50. R_SUCCEED();
  51. }
  52. Result IAudioIn::Start() {
  53. LOG_DEBUG(Service_Audio, "called");
  54. R_RETURN(impl->StartSystem());
  55. }
  56. Result IAudioIn::Stop() {
  57. LOG_DEBUG(Service_Audio, "called");
  58. R_RETURN(impl->StopSystem());
  59. }
  60. Result IAudioIn::AppendAudioInBuffer(InArray<AudioInBuffer, BufferAttr_HipcMapAlias> buffer,
  61. u64 buffer_client_ptr) {
  62. R_RETURN(this->AppendAudioInBufferAuto(buffer, buffer_client_ptr));
  63. }
  64. Result IAudioIn::AppendAudioInBufferAuto(InArray<AudioInBuffer, BufferAttr_HipcAutoSelect> buffer,
  65. u64 buffer_client_ptr) {
  66. if (buffer.empty()) {
  67. LOG_ERROR(Service_Audio, "Input buffer is too small for an AudioInBuffer!");
  68. R_THROW(Audio::ResultInsufficientBuffer);
  69. }
  70. [[maybe_unused]] const auto session_id{impl->GetSystem().GetSessionId()};
  71. LOG_TRACE(Service_Audio, "called. Session {} Appending buffer {:08X}", session_id,
  72. buffer_client_ptr);
  73. R_RETURN(impl->AppendBuffer(buffer[0], buffer_client_ptr));
  74. }
  75. Result IAudioIn::RegisterBufferEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
  76. LOG_DEBUG(Service_Audio, "called");
  77. *out_event = &impl->GetBufferEvent();
  78. R_SUCCEED();
  79. }
  80. Result IAudioIn::GetReleasedAudioInBuffers(OutArray<u64, BufferAttr_HipcMapAlias> out_audio_buffer,
  81. Out<u32> out_count) {
  82. R_RETURN(this->GetReleasedAudioInBuffersAuto(out_audio_buffer, out_count));
  83. }
  84. Result IAudioIn::GetReleasedAudioInBuffersAuto(
  85. OutArray<u64, BufferAttr_HipcAutoSelect> out_audio_buffer, Out<u32> out_count) {
  86. if (!out_audio_buffer.empty()) {
  87. out_audio_buffer[0] = 0;
  88. }
  89. *out_count = impl->GetReleasedBuffers(out_audio_buffer);
  90. LOG_TRACE(Service_Audio, "called. Session {} released {} buffers",
  91. impl->GetSystem().GetSessionId(), *out_count);
  92. R_SUCCEED();
  93. }
  94. Result IAudioIn::ContainsAudioInBuffer(Out<bool> out_contains_buffer, u64 buffer_client_ptr) {
  95. *out_contains_buffer = impl->ContainsAudioBuffer(buffer_client_ptr);
  96. LOG_DEBUG(Service_Audio, "called. Is buffer {:08X} registered? {}", buffer_client_ptr,
  97. *out_contains_buffer);
  98. R_SUCCEED();
  99. }
  100. Result IAudioIn::GetAudioInBufferCount(Out<u32> out_buffer_count) {
  101. *out_buffer_count = impl->GetBufferCount();
  102. LOG_DEBUG(Service_Audio, "called. Buffer count={}", *out_buffer_count);
  103. R_SUCCEED();
  104. }
  105. Result IAudioIn::SetDeviceGain(f32 device_gain) {
  106. impl->SetVolume(device_gain);
  107. LOG_DEBUG(Service_Audio, "called. Gain {}", device_gain);
  108. R_SUCCEED();
  109. }
  110. Result IAudioIn::GetDeviceGain(Out<f32> out_device_gain) {
  111. *out_device_gain = impl->GetVolume();
  112. LOG_DEBUG(Service_Audio, "called. Gain {}", *out_device_gain);
  113. R_SUCCEED();
  114. }
  115. Result IAudioIn::FlushAudioInBuffers(Out<bool> out_flushed) {
  116. *out_flushed = impl->FlushAudioInBuffers();
  117. LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", *out_flushed);
  118. R_SUCCEED();
  119. }
  120. } // namespace Service::Audio