diff options
| -rw-r--r-- | src/audio_core/device/device_session.cpp | 14 | ||||
| -rw-r--r-- | src/audio_core/device/device_session.h | 12 | ||||
| -rw-r--r-- | src/audio_core/in/audio_in_system.cpp | 2 | ||||
| -rw-r--r-- | src/audio_core/in/audio_in_system.h | 13 | ||||
| -rw-r--r-- | src/audio_core/out/audio_out_system.cpp | 4 | ||||
| -rw-r--r-- | src/audio_core/out/audio_out_system.h | 13 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audin_u.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audout_u.cpp | 26 | 
8 files changed, 85 insertions, 35 deletions
| diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp index ee42ae529..3c214ec00 100644 --- a/src/audio_core/device/device_session.cpp +++ b/src/audio_core/device/device_session.cpp @@ -10,6 +10,8 @@  #include "core/core_timing.h"  #include "core/memory.h" +#include "core/hle/kernel/k_process.h" +  namespace AudioCore {  using namespace std::literals; @@ -25,7 +27,7 @@ DeviceSession::~DeviceSession() {  }  Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_format_, -                                 u16 channel_count_, size_t session_id_, u32 handle_, +                                 u16 channel_count_, size_t session_id_, Kernel::KProcess* handle_,                                   u64 applet_resource_user_id_, Sink::StreamType type_) {      if (stream) {          Finalize(); @@ -36,6 +38,7 @@ Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_for      channel_count = channel_count_;      session_id = session_id_;      handle = handle_; +    handle->Open();      applet_resource_user_id = applet_resource_user_id_;      if (type == Sink::StreamType::In) { @@ -54,6 +57,11 @@ void DeviceSession::Finalize() {          sink->CloseStream(stream);          stream = nullptr;      } + +    if (handle) { +        handle->Close(); +        handle = nullptr; +    }  }  void DeviceSession::Start() { @@ -91,7 +99,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) {              stream->AppendBuffer(new_buffer, tmp_samples);          } else {              Core::Memory::CpuGuestMemory<s16, Core::Memory::GuestMemoryFlags::UnsafeRead> samples( -                system.ApplicationMemory(), buffer.samples, buffer.size / sizeof(s16)); +                handle->GetMemory(), buffer.samples, buffer.size / sizeof(s16));              stream->AppendBuffer(new_buffer, samples);          }      } @@ -100,7 +108,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) {  void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const {      if (type == Sink::StreamType::In) {          auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))}; -        system.ApplicationMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size); +        handle->GetMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size);      }  } diff --git a/src/audio_core/device/device_session.h b/src/audio_core/device/device_session.h index 7d52f362d..f3fae2617 100644 --- a/src/audio_core/device/device_session.h +++ b/src/audio_core/device/device_session.h @@ -20,6 +20,10 @@ struct EventType;  } // namespace Timing  } // namespace Core +namespace Kernel { +class KProcess; +} // namespace Kernel +  namespace AudioCore {  namespace Sink { @@ -44,13 +48,13 @@ public:       * @param sample_format           - Sample format for this device's output.       * @param channel_count           - Number of channels for this device (2 or 6).       * @param session_id              - This session's id. -     * @param handle                  - Handle for this device session (unused). +     * @param handle                  - Process handle for this device session.       * @param applet_resource_user_id - Applet resource user id for this device session (unused).       * @param type                    - Type of this stream (Render, In, Out).       * @return Result code for this call.       */      Result Initialize(std::string_view name, SampleFormat sample_format, u16 channel_count, -                      size_t session_id, u32 handle, u64 applet_resource_user_id, +                      size_t session_id, Kernel::KProcess* handle, u64 applet_resource_user_id,                        Sink::StreamType type);      /** @@ -137,8 +141,8 @@ private:      u16 channel_count{};      /// Session id of this device session      size_t session_id{}; -    /// Handle of this device session -    u32 handle{}; +    /// Process handle of device memory owner +    Kernel::KProcess* handle{};      /// Applet resource user id of this device session      u64 applet_resource_user_id{};      /// Total number of samples played by this device session diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp index 579129121..b2dd3ef9f 100644 --- a/src/audio_core/in/audio_in_system.cpp +++ b/src/audio_core/in/audio_in_system.cpp @@ -57,7 +57,7 @@ Result System::IsConfigValid(const std::string_view device_name,  }  Result System::Initialize(std::string device_name, const AudioInParameter& in_params, -                          const u32 handle_, const u64 applet_resource_user_id_) { +                          Kernel::KProcess* handle_, const u64 applet_resource_user_id_) {      auto result{IsConfigValid(device_name, in_params)};      if (result.IsError()) {          return result; diff --git a/src/audio_core/in/audio_in_system.h b/src/audio_core/in/audio_in_system.h index 1c5154638..ee048190c 100644 --- a/src/audio_core/in/audio_in_system.h +++ b/src/audio_core/in/audio_in_system.h @@ -19,7 +19,8 @@ class System;  namespace Kernel {  class KEvent; -} +class KProcess; +} // namespace Kernel  namespace AudioCore::AudioIn { @@ -93,12 +94,12 @@ public:       *       * @param device_name             - The name of the requested input device.       * @param in_params               - Input parameters, see AudioInParameter. -     * @param handle                  - Unused. +     * @param handle                  - Process handle.       * @param applet_resource_user_id - Unused.       * @return Result code.       */ -    Result Initialize(std::string device_name, const AudioInParameter& in_params, u32 handle, -                      u64 applet_resource_user_id); +    Result Initialize(std::string device_name, const AudioInParameter& in_params, +                      Kernel::KProcess* handle, u64 applet_resource_user_id);      /**       * Start this system. @@ -244,8 +245,8 @@ public:  private:      /// Core system      Core::System& system; -    /// (Unused) -    u32 handle{}; +    /// Process handle +    Kernel::KProcess* handle{};      /// (Unused)      u64 applet_resource_user_id{};      /// Buffer event, signalled when a buffer is ready diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp index 0adf64bd3..7b3ff4e88 100644 --- a/src/audio_core/out/audio_out_system.cpp +++ b/src/audio_core/out/audio_out_system.cpp @@ -48,8 +48,8 @@ Result System::IsConfigValid(std::string_view device_name,      return Service::Audio::ResultInvalidChannelCount;  } -Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_, -                          u64 applet_resource_user_id_) { +Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, +                          Kernel::KProcess* handle_, u64 applet_resource_user_id_) {      auto result = IsConfigValid(device_name, in_params);      if (result.IsError()) {          return result; diff --git a/src/audio_core/out/audio_out_system.h b/src/audio_core/out/audio_out_system.h index b95cb91be..82aada185 100644 --- a/src/audio_core/out/audio_out_system.h +++ b/src/audio_core/out/audio_out_system.h @@ -19,7 +19,8 @@ class System;  namespace Kernel {  class KEvent; -} +class KProcess; +} // namespace Kernel  namespace AudioCore::AudioOut { @@ -84,12 +85,12 @@ public:       *       * @param device_name             - The name of the requested output device.       * @param in_params               - Input parameters, see AudioOutParameter. -     * @param handle                  - Unused. +     * @param handle                  - Process handle.       * @param applet_resource_user_id - Unused.       * @return Result code.       */ -    Result Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle, -                      u64 applet_resource_user_id); +    Result Initialize(std::string device_name, const AudioOutParameter& in_params, +                      Kernel::KProcess* handle, u64 applet_resource_user_id);      /**       * Start this system. @@ -228,8 +229,8 @@ public:  private:      /// Core system      Core::System& system; -    /// (Unused) -    u32 handle{}; +    /// Process handle +    Kernel::KProcess* handle{};      /// (Unused)      u64 applet_resource_user_id{};      /// Buffer event, signalled when a buffer is ready diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index 56fee4591..de2aa6906 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp @@ -18,11 +18,11 @@ using namespace AudioCore::AudioIn;  class IAudioIn final : public ServiceFramework<IAudioIn> {  public:      explicit IAudioIn(Core::System& system_, Manager& manager, size_t session_id, -                      const std::string& device_name, const AudioInParameter& in_params, u32 handle, -                      u64 applet_resource_user_id) +                      const std::string& device_name, const AudioInParameter& in_params, +                      Kernel::KProcess* handle, u64 applet_resource_user_id)          : ServiceFramework{system_, "IAudioIn"},            service_context{system_, "IAudioIn"}, event{service_context.CreateEvent("AudioInEvent")}, -          impl{std::make_shared<In>(system_, manager, event, session_id)} { +          process{handle}, impl{std::make_shared<In>(system_, manager, event, session_id)} {          // clang-format off          static const FunctionInfo functions[] = {              {0, &IAudioIn::GetAudioInState, "GetAudioInState"}, @@ -45,6 +45,8 @@ public:          RegisterHandlers(functions); +        process->Open(); +          if (impl->GetSystem()                  .Initialize(device_name, in_params, handle, applet_resource_user_id)                  .IsError()) { @@ -55,6 +57,7 @@ public:      ~IAudioIn() override {          impl->Free();          service_context.CloseEvent(event); +        process->Close();      }      [[nodiscard]] std::shared_ptr<In> GetImpl() { @@ -196,6 +199,7 @@ private:      KernelHelpers::ServiceContext service_context;      Kernel::KEvent* event; +    Kernel::KProcess* process;      std::shared_ptr<AudioCore::AudioIn::In> impl;      Common::ScratchBuffer<u64> released_buffer;  }; @@ -267,6 +271,14 @@ void AudInU::OpenAudioIn(HLERequestContext& ctx) {      auto device_name = Common::StringFromBuffer(device_name_data);      auto handle{ctx.GetCopyHandle(0)}; +    auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)}; +    if (process.IsNull()) { +        LOG_ERROR(Service_Audio, "Failed to get process handle"); +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(ResultUnknown); +        return; +    } +      std::scoped_lock l{impl->mutex};      auto link{impl->LinkToManager()};      if (link.IsError()) { @@ -287,8 +299,9 @@ void AudInU::OpenAudioIn(HLERequestContext& ctx) {      LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id,                impl->num_free_sessions); -    auto audio_in = std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, -                                               in_params, handle, applet_resource_user_id); +    auto audio_in = +        std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, in_params, +                                   process.GetPointerUnsafe(), applet_resource_user_id);      impl->sessions[new_session_id] = audio_in->GetImpl();      impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; @@ -318,6 +331,14 @@ void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) {      auto device_name = Common::StringFromBuffer(device_name_data);      auto handle{ctx.GetCopyHandle(0)}; +    auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)}; +    if (process.IsNull()) { +        LOG_ERROR(Service_Audio, "Failed to get process handle"); +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(ResultUnknown); +        return; +    } +      std::scoped_lock l{impl->mutex};      auto link{impl->LinkToManager()};      if (link.IsError()) { @@ -338,8 +359,9 @@ void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) {      LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id,                impl->num_free_sessions); -    auto audio_in = std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, -                                               in_params, handle, applet_resource_user_id); +    auto audio_in = +        std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, in_params, +                                   process.GetPointerUnsafe(), applet_resource_user_id);      impl->sessions[new_session_id] = audio_in->GetImpl();      impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id; diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index ca683d72c..8cc7b69f4 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -26,9 +26,10 @@ class IAudioOut final : public ServiceFramework<IAudioOut> {  public:      explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,                         size_t session_id, const std::string& device_name, -                       const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) +                       const AudioOutParameter& in_params, Kernel::KProcess* handle, +                       u64 applet_resource_user_id)          : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"}, -          event{service_context.CreateEvent("AudioOutEvent")}, +          event{service_context.CreateEvent("AudioOutEvent")}, process{handle},            impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {          // clang-format off @@ -50,11 +51,14 @@ public:          };          // clang-format on          RegisterHandlers(functions); + +        process->Open();      }      ~IAudioOut() override {          impl->Free();          service_context.CloseEvent(event); +        process->Close();      }      [[nodiscard]] std::shared_ptr<AudioCore::AudioOut::Out> GetImpl() { @@ -206,6 +210,7 @@ private:      KernelHelpers::ServiceContext service_context;      Kernel::KEvent* event; +    Kernel::KProcess* process;      std::shared_ptr<AudioCore::AudioOut::Out> impl;      Common::ScratchBuffer<u64> released_buffer;  }; @@ -257,6 +262,14 @@ void AudOutU::OpenAudioOut(HLERequestContext& ctx) {      auto device_name = Common::StringFromBuffer(device_name_data);      auto handle{ctx.GetCopyHandle(0)}; +    auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)}; +    if (process.IsNull()) { +        LOG_ERROR(Service_Audio, "Failed to get process handle"); +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(ResultUnknown); +        return; +    } +      auto link{impl->LinkToManager()};      if (link.IsError()) {          LOG_ERROR(Service_Audio, "Failed to link Audio Out to Audio Manager"); @@ -276,10 +289,11 @@ void AudOutU::OpenAudioOut(HLERequestContext& ctx) {      LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,                impl->num_free_sessions); -    auto audio_out = std::make_shared<IAudioOut>(system, *impl, new_session_id, device_name, -                                                 in_params, handle, applet_resource_user_id); -    result = audio_out->GetImpl()->GetSystem().Initialize(device_name, in_params, handle, -                                                          applet_resource_user_id); +    auto audio_out = +        std::make_shared<IAudioOut>(system, *impl, new_session_id, device_name, in_params, +                                    process.GetPointerUnsafe(), applet_resource_user_id); +    result = audio_out->GetImpl()->GetSystem().Initialize( +        device_name, in_params, process.GetPointerUnsafe(), applet_resource_user_id);      if (result.IsError()) {          LOG_ERROR(Service_Audio, "Failed to initialize the AudioOut System!");          IPC::ResponseBuilder rb{ctx, 2}; | 
