device_session.h 4.3 KB

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