device_session.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <chrono>
  5. #include <memory>
  6. #include <optional>
  7. #include <span>
  8. #include "audio_core/common/common.h"
  9. #include "audio_core/sink/sink.h"
  10. #include "core/hle/service/audio/errors.h"
  11. namespace Core {
  12. class System;
  13. namespace Timing {
  14. struct EventType;
  15. } // namespace Timing
  16. } // namespace Core
  17. namespace AudioCore {
  18. namespace Sink {
  19. class SinkStream;
  20. struct SinkBuffer;
  21. } // namespace Sink
  22. struct AudioBuffer;
  23. /**
  24. * Represents an input or output device stream for audio in and audio out (not used for render).
  25. **/
  26. class DeviceSession {
  27. public:
  28. explicit DeviceSession(Core::System& system);
  29. ~DeviceSession();
  30. /**
  31. * Initialize this device session.
  32. *
  33. * @param name - Name of this device.
  34. * @param sample_format - Sample format for this device's output.
  35. * @param channel_count - Number of channels for this device (2 or 6).
  36. * @param session_id - This session's id.
  37. * @param handle - Handle for this device session (unused).
  38. * @param applet_resource_user_id - Applet resource user id for this device session (unused).
  39. * @param type - Type of this stream (Render, In, Out).
  40. * @return Result code for this call.
  41. */
  42. Result Initialize(std::string_view name, SampleFormat sample_format, u16 channel_count,
  43. size_t session_id, u32 handle, u64 applet_resource_user_id,
  44. Sink::StreamType type);
  45. /**
  46. * Finalize this device session.
  47. */
  48. void Finalize();
  49. /**
  50. * Append audio buffers to this device session to be played back.
  51. *
  52. * @param buffers - The buffers to play.
  53. */
  54. void AppendBuffers(std::span<AudioBuffer> buffers) const;
  55. /**
  56. * (Audio In only) Pop samples from the backend, and write them back to this buffer's address.
  57. *
  58. * @param buffer - The buffer to write to.
  59. */
  60. void ReleaseBuffer(AudioBuffer& buffer) const;
  61. /**
  62. * Check if the buffer for the given tag has been consumed by the backend.
  63. *
  64. * @param buffer - the buffer to check.
  65. *
  66. * @return true if the buffer has been consumed, otherwise false.
  67. */
  68. bool IsBufferConsumed(AudioBuffer& buffer) const;
  69. /**
  70. * Start this device session, starting the backend stream.
  71. */
  72. void Start();
  73. /**
  74. * Stop this device session, stopping the backend stream.
  75. */
  76. void Stop();
  77. /**
  78. * Set this device session's volume.
  79. *
  80. * @param volume - New volume for this session.
  81. */
  82. void SetVolume(f32 volume) const;
  83. /**
  84. * Get this device session's total played sample count.
  85. *
  86. * @return Samples played by this session.
  87. */
  88. u64 GetPlayedSampleCount() const;
  89. /*
  90. * CoreTiming callback to increment played_sample_count over time.
  91. */
  92. std::optional<std::chrono::nanoseconds> ThreadFunc();
  93. /*
  94. * Set the size of the ring buffer.
  95. */
  96. void SetRingSize(u32 ring_size);
  97. private:
  98. /// System
  99. Core::System& system;
  100. /// Output sink this device will use
  101. Sink::Sink* sink{};
  102. /// The backend stream for this device session to send samples to
  103. Sink::SinkStream* stream{};
  104. /// Name of this device session
  105. std::string name{};
  106. /// Type of this device session (render/in/out)
  107. Sink::StreamType type{};
  108. /// Sample format for this device.
  109. SampleFormat sample_format{SampleFormat::PcmInt16};
  110. /// Channel count for this device session
  111. u16 channel_count{};
  112. /// Session id of this device session
  113. size_t session_id{};
  114. /// Handle of this device session
  115. u32 handle{};
  116. /// Applet resource user id of this device session
  117. u64 applet_resource_user_id{};
  118. /// Total number of samples played by this device session
  119. std::atomic<u64> played_sample_count{};
  120. /// Event increasing the played sample count every 5ms
  121. std::shared_ptr<Core::Timing::EventType> thread_event;
  122. /// Is this session initialised?
  123. bool initialized{};
  124. /// Buffer queue
  125. std::vector<AudioBuffer> buffer_queue{};
  126. };
  127. } // namespace AudioCore