diff options
| author | 2018-07-30 20:29:17 -0700 | |
|---|---|---|
| committer | 2018-07-30 20:29:17 -0700 | |
| commit | bf9c62bc76a2296c1a81cfc1b83aaf4028578901 (patch) | |
| tree | dad8906c597af3f579d4f72f4c9f493503c40665 /src/audio_core/stream.cpp | |
| parent | Port #3758 from Citra (#852): Add missing std::string import in text_formatter (diff) | |
| parent | audio_core: Implement Sink and SinkStream interfaces with cubeb. (diff) | |
| download | yuzu-bf9c62bc76a2296c1a81cfc1b83aaf4028578901.tar.gz yuzu-bf9c62bc76a2296c1a81cfc1b83aaf4028578901.tar.xz yuzu-bf9c62bc76a2296c1a81cfc1b83aaf4028578901.zip | |
Merge pull request #855 from bunnei/cubeb
Audio output backend based on cubeb
Diffstat (limited to 'src/audio_core/stream.cpp')
| -rw-r--r-- | src/audio_core/stream.cpp | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index 82bff4b9e..689f51a1d 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp | |||
| @@ -7,30 +7,37 @@ | |||
| 7 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/core_timing_util.h" | 8 | #include "core/core_timing_util.h" |
| 9 | 9 | ||
| 10 | #include "audio_core/sink.h" | ||
| 11 | #include "audio_core/sink_details.h" | ||
| 10 | #include "audio_core/stream.h" | 12 | #include "audio_core/stream.h" |
| 11 | 13 | ||
| 12 | namespace AudioCore { | 14 | namespace AudioCore { |
| 13 | 15 | ||
| 14 | constexpr size_t MaxAudioBufferCount{32}; | 16 | constexpr size_t MaxAudioBufferCount{32}; |
| 15 | 17 | ||
| 16 | /// Returns the sample size for the specified audio stream format | 18 | u32 Stream::GetNumChannels() const { |
| 17 | static size_t SampleSizeFromFormat(Stream::Format format) { | ||
| 18 | switch (format) { | 19 | switch (format) { |
| 19 | case Stream::Format::Mono16: | 20 | case Format::Mono16: |
| 21 | return 1; | ||
| 22 | case Format::Stereo16: | ||
| 20 | return 2; | 23 | return 2; |
| 21 | case Stream::Format::Stereo16: | 24 | case Format::Multi51Channel16: |
| 22 | return 4; | 25 | return 6; |
| 23 | case Stream::Format::Multi51Channel16: | 26 | } |
| 24 | return 12; | ||
| 25 | }; | ||
| 26 | |||
| 27 | LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format)); | 27 | LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format)); |
| 28 | UNREACHABLE(); | 28 | UNREACHABLE(); |
| 29 | return {}; | 29 | return {}; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | Stream::Stream(int sample_rate, Format format, ReleaseCallback&& release_callback) | 32 | u32 Stream::GetSampleSize() const { |
| 33 | : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)} { | 33 | return GetNumChannels() * 2; |
| 34 | } | ||
| 35 | |||
| 36 | Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback, | ||
| 37 | SinkStream& sink_stream) | ||
| 38 | : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, | ||
| 39 | sink_stream{sink_stream} { | ||
| 40 | |||
| 34 | release_event = CoreTiming::RegisterEvent( | 41 | release_event = CoreTiming::RegisterEvent( |
| 35 | "Stream::Release", [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); }); | 42 | "Stream::Release", [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); }); |
| 36 | } | 43 | } |
| @@ -45,7 +52,7 @@ void Stream::Stop() { | |||
| 45 | } | 52 | } |
| 46 | 53 | ||
| 47 | s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { | 54 | s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { |
| 48 | const size_t num_samples{buffer.GetData().size() / SampleSizeFromFormat(format)}; | 55 | const size_t num_samples{buffer.GetData().size() / GetSampleSize()}; |
| 49 | return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); | 56 | return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); |
| 50 | } | 57 | } |
| 51 | 58 | ||
| @@ -68,6 +75,10 @@ void Stream::PlayNextBuffer() { | |||
| 68 | active_buffer = queued_buffers.front(); | 75 | active_buffer = queued_buffers.front(); |
| 69 | queued_buffers.pop(); | 76 | queued_buffers.pop(); |
| 70 | 77 | ||
| 78 | sink_stream.EnqueueSamples(GetNumChannels(), | ||
| 79 | reinterpret_cast<const s16*>(active_buffer->GetData().data()), | ||
| 80 | active_buffer->GetData().size() / GetSampleSize()); | ||
| 81 | |||
| 71 | CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); | 82 | CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); |
| 72 | } | 83 | } |
| 73 | 84 | ||