audio_out_system.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <atomic>
  5. #include <memory>
  6. #include <span>
  7. #include <string>
  8. #include "audio_core/common/common.h"
  9. #include "audio_core/device/audio_buffers.h"
  10. #include "audio_core/device/device_session.h"
  11. #include "core/hle/service/audio/errors.h"
  12. namespace Core {
  13. class System;
  14. }
  15. namespace Kernel {
  16. class KEvent;
  17. }
  18. namespace AudioCore::AudioOut {
  19. constexpr SessionTypes SessionType = SessionTypes::AudioOut;
  20. struct AudioOutParameter {
  21. /* 0x0 */ s32_le sample_rate;
  22. /* 0x4 */ u16_le channel_count;
  23. /* 0x6 */ u16_le reserved;
  24. };
  25. static_assert(sizeof(AudioOutParameter) == 0x8, "AudioOutParameter is an invalid size");
  26. struct AudioOutParameterInternal {
  27. /* 0x0 */ u32_le sample_rate;
  28. /* 0x4 */ u32_le channel_count;
  29. /* 0x8 */ u32_le sample_format;
  30. /* 0xC */ u32_le state;
  31. };
  32. static_assert(sizeof(AudioOutParameterInternal) == 0x10,
  33. "AudioOutParameterInternal is an invalid size");
  34. struct AudioOutBuffer {
  35. /* 0x00 */ AudioOutBuffer* next;
  36. /* 0x08 */ VAddr samples;
  37. /* 0x10 */ u64 capacity;
  38. /* 0x18 */ u64 size;
  39. /* 0x20 */ u64 offset;
  40. };
  41. static_assert(sizeof(AudioOutBuffer) == 0x28, "AudioOutBuffer is an invalid size");
  42. enum class State {
  43. Started,
  44. Stopped,
  45. };
  46. /**
  47. * Controls and drives audio output.
  48. */
  49. class System {
  50. public:
  51. explicit System(Core::System& system, Kernel::KEvent* event, size_t session_id);
  52. ~System();
  53. /**
  54. * Get the default audio output device name.
  55. *
  56. * @return The default audio output device name.
  57. */
  58. std::string_view GetDefaultOutputDeviceName();
  59. /**
  60. * Is the given initialize config valid?
  61. *
  62. * @param device_name - The name of the requested output device.
  63. * @param in_params - Input parameters, see AudioOutParameter.
  64. * @return Result code.
  65. */
  66. Result IsConfigValid(std::string_view device_name, const AudioOutParameter& in_params);
  67. /**
  68. * Initialize this system.
  69. *
  70. * @param device_name - The name of the requested output device.
  71. * @param in_params - Input parameters, see AudioOutParameter.
  72. * @param handle - Unused.
  73. * @param applet_resource_user_id - Unused.
  74. * @return Result code.
  75. */
  76. Result Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle,
  77. u64& applet_resource_user_id);
  78. /**
  79. * Start this system.
  80. *
  81. * @return Result code.
  82. */
  83. Result Start();
  84. /**
  85. * Stop this system.
  86. *
  87. * @return Result code.
  88. */
  89. Result Stop();
  90. /**
  91. * Finalize this system.
  92. */
  93. void Finalize();
  94. /**
  95. * Start this system's device session.
  96. */
  97. void StartSession();
  98. /**
  99. * Get this system's id.
  100. */
  101. size_t GetSessionId() const;
  102. /**
  103. * Append a new buffer to the device.
  104. *
  105. * @param buffer - New buffer to append.
  106. * @param tag - Unique tag of the buffer.
  107. * @return True if the buffer was appended, otherwise false.
  108. */
  109. bool AppendBuffer(const AudioOutBuffer& buffer, u64 tag);
  110. /**
  111. * Register all appended buffers.
  112. */
  113. void RegisterBuffers();
  114. /**
  115. * Release all registered buffers.
  116. */
  117. void ReleaseBuffers();
  118. /**
  119. * Get all released buffers.
  120. *
  121. * @param tags - Container to be filled with the released buffers' tags.
  122. * @return The number of buffers released.
  123. */
  124. u32 GetReleasedBuffers(std::span<u64> tags);
  125. /**
  126. * Flush all appended and registered buffers.
  127. *
  128. * @return True if buffers were successfully flushed, otherwise false.
  129. */
  130. bool FlushAudioOutBuffers();
  131. /**
  132. * Get this system's current channel count.
  133. *
  134. * @return The channel count.
  135. */
  136. u16 GetChannelCount() const;
  137. /**
  138. * Get this system's current sample rate.
  139. *
  140. * @return The sample rate.
  141. */
  142. u32 GetSampleRate() const;
  143. /**
  144. * Get this system's current sample format.
  145. *
  146. * @return The sample format.
  147. */
  148. SampleFormat GetSampleFormat() const;
  149. /**
  150. * Get this system's current state.
  151. *
  152. * @return The current state.
  153. */
  154. State GetState();
  155. /**
  156. * Get this system's name.
  157. *
  158. * @return The system's name.
  159. */
  160. std::string GetName() const;
  161. /**
  162. * Get this system's current volume.
  163. *
  164. * @return The system's current volume.
  165. */
  166. f32 GetVolume() const;
  167. /**
  168. * Set this system's current volume.
  169. *
  170. * @param The new volume.
  171. */
  172. void SetVolume(f32 volume);
  173. /**
  174. * Does the system contain this buffer?
  175. *
  176. * @param tag - Unique tag to search for.
  177. * @return True if the buffer is in the system, otherwise false.
  178. */
  179. bool ContainsAudioBuffer(u64 tag);
  180. /**
  181. * Get the maximum number of usable buffers (default 32).
  182. *
  183. * @return The number of buffers.
  184. */
  185. u32 GetBufferCount();
  186. /**
  187. * Get the total number of samples played by this system.
  188. *
  189. * @return The number of samples.
  190. */
  191. u64 GetPlayedSampleCount() const;
  192. private:
  193. /// Core system
  194. Core::System& system;
  195. /// (Unused)
  196. u32 handle{};
  197. /// (Unused)
  198. u64 applet_resource_user_id{};
  199. /// Buffer event, signalled when a buffer is ready
  200. Kernel::KEvent* buffer_event;
  201. /// Session id of this system
  202. size_t session_id{};
  203. /// Device session for this system
  204. std::unique_ptr<DeviceSession> session;
  205. /// Audio buffers in use by this system
  206. AudioBuffers<BufferCount> buffers{BufferCount};
  207. /// Sample rate of this system
  208. u32 sample_rate{};
  209. /// Sample format of this system
  210. SampleFormat sample_format{SampleFormat::PcmInt16};
  211. /// Channel count of this system
  212. u16 channel_count{};
  213. /// State of this system
  214. std::atomic<State> state{State::Stopped};
  215. /// Name of this system
  216. std::string name{};
  217. /// Volume of this system
  218. f32 volume{1.0f};
  219. };
  220. } // namespace AudioCore::AudioOut