audio_manager.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "audio_core/audio_manager.h"
  4. #include "core/core.h"
  5. #include "core/hle/service/audio/errors.h"
  6. namespace AudioCore {
  7. AudioManager::AudioManager() {
  8. thread = std::jthread([this]() { ThreadFunc(); });
  9. }
  10. void AudioManager::Shutdown() {
  11. running = false;
  12. events.SetAudioEvent(Event::Type::Max, true);
  13. thread.join();
  14. }
  15. Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
  16. if (!running) {
  17. return Service::Audio::ResultOperationFailed;
  18. }
  19. std::scoped_lock l{lock};
  20. const auto index{events.GetManagerIndex(Event::Type::AudioOutManager)};
  21. if (buffer_events[index] == nullptr) {
  22. buffer_events[index] = std::move(buffer_func);
  23. needs_update = true;
  24. events.SetAudioEvent(Event::Type::AudioOutManager, true);
  25. }
  26. return ResultSuccess;
  27. }
  28. Result AudioManager::SetInManager(BufferEventFunc buffer_func) {
  29. if (!running) {
  30. return Service::Audio::ResultOperationFailed;
  31. }
  32. std::scoped_lock l{lock};
  33. const auto index{events.GetManagerIndex(Event::Type::AudioInManager)};
  34. if (buffer_events[index] == nullptr) {
  35. buffer_events[index] = std::move(buffer_func);
  36. needs_update = true;
  37. events.SetAudioEvent(Event::Type::AudioInManager, true);
  38. }
  39. return ResultSuccess;
  40. }
  41. void AudioManager::SetEvent(const Event::Type type, const bool signalled) {
  42. events.SetAudioEvent(type, signalled);
  43. }
  44. void AudioManager::ThreadFunc() {
  45. std::unique_lock l{events.GetAudioEventLock()};
  46. events.ClearEvents();
  47. running = true;
  48. while (running) {
  49. const auto timed_out{events.Wait(l, std::chrono::seconds(2))};
  50. if (events.CheckAudioEventSet(Event::Type::Max)) {
  51. break;
  52. }
  53. for (size_t i = 0; i < buffer_events.size(); i++) {
  54. const auto event_type = static_cast<Event::Type>(i);
  55. if (events.CheckAudioEventSet(event_type) || timed_out) {
  56. if (buffer_events[i]) {
  57. buffer_events[i]();
  58. }
  59. }
  60. events.SetAudioEvent(event_type, false);
  61. }
  62. }
  63. }
  64. } // namespace AudioCore