stream.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2018 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <chrono>
  6. #include <functional>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include <queue>
  11. #include "audio_core/buffer.h"
  12. #include "common/common_types.h"
  13. namespace Core::Timing {
  14. class CoreTiming;
  15. struct EventType;
  16. } // namespace Core::Timing
  17. namespace AudioCore {
  18. class SinkStream;
  19. /**
  20. * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut
  21. */
  22. class Stream {
  23. public:
  24. /// Audio format of the stream
  25. enum class Format {
  26. Mono16,
  27. Stereo16,
  28. Multi51Channel16,
  29. };
  30. /// Current state of the stream
  31. enum class State {
  32. Stopped,
  33. Playing,
  34. };
  35. /// Callback function type, used to change guest state on a buffer being released
  36. using ReleaseCallback = std::function<void()>;
  37. Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_,
  38. ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_);
  39. /// Plays the audio stream
  40. void Play();
  41. /// Stops the audio stream
  42. void Stop();
  43. /// Queues a buffer into the audio stream, returns true on success
  44. bool QueueBuffer(BufferPtr&& buffer);
  45. /// Returns true if the audio stream contains a buffer with the specified tag
  46. [[nodiscard]] bool ContainsBuffer(Buffer::Tag tag) const;
  47. /// Returns a vector of recently released buffers specified by tag
  48. [[nodiscard]] std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count);
  49. /// Returns a vector of all recently released buffers specified by tag
  50. [[nodiscard]] std::vector<Buffer::Tag> GetTagsAndReleaseBuffers();
  51. void SetVolume(float volume);
  52. [[nodiscard]] float GetVolume() const {
  53. return game_volume;
  54. }
  55. /// Returns true if the stream is currently playing
  56. [[nodiscard]] bool IsPlaying() const {
  57. return state == State::Playing;
  58. }
  59. /// Returns the number of queued buffers
  60. [[nodiscard]] std::size_t GetQueueSize() const {
  61. return queued_buffers.size();
  62. }
  63. /// Gets the sample rate
  64. [[nodiscard]] u32 GetSampleRate() const {
  65. return sample_rate;
  66. }
  67. /// Gets the number of channels
  68. [[nodiscard]] u32 GetNumChannels() const;
  69. /// Get the state
  70. [[nodiscard]] State GetState() const;
  71. private:
  72. /// Plays the next queued buffer in the audio stream, starting playback if necessary
  73. void PlayNextBuffer(std::chrono::nanoseconds ns_late = {});
  74. /// Releases the actively playing buffer, signalling that it has been completed
  75. void ReleaseActiveBuffer(std::chrono::nanoseconds ns_late = {});
  76. /// Gets the number of core cycles when the specified buffer will be released
  77. [[nodiscard]] std::chrono::nanoseconds GetBufferReleaseNS(const Buffer& buffer) const;
  78. u32 sample_rate; ///< Sample rate of the stream
  79. Format format; ///< Format of the stream
  80. float game_volume = 1.0f; ///< The volume the game currently has set
  81. ReleaseCallback release_callback; ///< Buffer release callback for the stream
  82. State state{State::Stopped}; ///< Playback state of the stream
  83. std::shared_ptr<Core::Timing::EventType>
  84. release_event; ///< Core timing release event for the stream
  85. BufferPtr active_buffer; ///< Actively playing buffer in the stream
  86. std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream
  87. std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
  88. SinkStream& sink_stream; ///< Output sink for the stream
  89. Core::Timing::CoreTiming& core_timing; ///< Core timing instance.
  90. std::string name; ///< Name of the stream, must be unique
  91. };
  92. using StreamPtr = std::shared_ptr<Stream>;
  93. } // namespace AudioCore