diff options
| author | 2020-07-01 16:52:02 +1000 | |
|---|---|---|
| committer | 2020-07-01 16:52:02 +1000 | |
| commit | 24c2930012baa60379da6f8c23f2cf35e38ef2d2 (patch) | |
| tree | 31a12f27494d72f5e5dcdbc886daded0d3e4dfed /src | |
| parent | Merge pull request #4217 from lioncash/prototype (diff) | |
| download | yuzu-24c2930012baa60379da6f8c23f2cf35e38ef2d2.tar.gz yuzu-24c2930012baa60379da6f8c23f2cf35e38ef2d2.tar.xz yuzu-24c2930012baa60379da6f8c23f2cf35e38ef2d2.zip | |
audio: Improving audio timing for multicore/single core
Fixes the issue with needing the timestretcher for multicore.
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/stream.cpp | 23 | ||||
| -rw-r--r-- | src/audio_core/stream.h | 4 |
2 files changed, 7 insertions, 20 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index dfc4805d9..307d78ecd 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp | |||
| @@ -38,7 +38,7 @@ Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format fo | |||
| 38 | sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { | 38 | sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { |
| 39 | 39 | ||
| 40 | release_event = Core::Timing::CreateEvent( | 40 | release_event = Core::Timing::CreateEvent( |
| 41 | name, [this](u64 userdata, s64 cycles_late) { ReleaseActiveBuffer(); }); | 41 | name, [this](u64 userdata, s64 cycles_late) { ReleaseActiveBuffer(cycles_late); }); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void Stream::Play() { | 44 | void Stream::Play() { |
| @@ -66,15 +66,6 @@ s64 Stream::GetBufferReleaseNS(const Buffer& buffer) const { | |||
| 66 | return ns.count(); | 66 | return ns.count(); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | s64 Stream::GetBufferReleaseNSHostTiming(const Buffer& buffer) const { | ||
| 70 | const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; | ||
| 71 | /// DSP signals before playing the last sample, in HLE we emulate this in this way | ||
| 72 | s64 base_samples = std::max<s64>(static_cast<s64>(num_samples) - 1, 0); | ||
| 73 | const auto ns = | ||
| 74 | std::chrono::nanoseconds((static_cast<u64>(base_samples) * 1000000000ULL) / sample_rate); | ||
| 75 | return ns.count(); | ||
| 76 | } | ||
| 77 | |||
| 78 | static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) { | 69 | static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) { |
| 79 | const float volume{std::clamp(Settings::Volume() - (1.0f - game_volume), 0.0f, 1.0f)}; | 70 | const float volume{std::clamp(Settings::Volume() - (1.0f - game_volume), 0.0f, 1.0f)}; |
| 80 | 71 | ||
| @@ -89,7 +80,7 @@ static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) { | |||
| 89 | } | 80 | } |
| 90 | } | 81 | } |
| 91 | 82 | ||
| 92 | void Stream::PlayNextBuffer() { | 83 | void Stream::PlayNextBuffer(s64 cycles_late) { |
| 93 | if (!IsPlaying()) { | 84 | if (!IsPlaying()) { |
| 94 | // Ensure we are in playing state before playing the next buffer | 85 | // Ensure we are in playing state before playing the next buffer |
| 95 | sink_stream.Flush(); | 86 | sink_stream.Flush(); |
| @@ -114,18 +105,14 @@ void Stream::PlayNextBuffer() { | |||
| 114 | 105 | ||
| 115 | sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); | 106 | sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); |
| 116 | 107 | ||
| 117 | if (core_timing.IsHostTiming()) { | 108 | core_timing.ScheduleEvent(GetBufferReleaseNS(*active_buffer) - cycles_late, release_event, {}); |
| 118 | core_timing.ScheduleEvent(GetBufferReleaseNSHostTiming(*active_buffer), release_event, {}); | ||
| 119 | } else { | ||
| 120 | core_timing.ScheduleEvent(GetBufferReleaseNS(*active_buffer), release_event, {}); | ||
| 121 | } | ||
| 122 | } | 109 | } |
| 123 | 110 | ||
| 124 | void Stream::ReleaseActiveBuffer() { | 111 | void Stream::ReleaseActiveBuffer(s64 cycles_late) { |
| 125 | ASSERT(active_buffer); | 112 | ASSERT(active_buffer); |
| 126 | released_buffers.push(std::move(active_buffer)); | 113 | released_buffers.push(std::move(active_buffer)); |
| 127 | release_callback(); | 114 | release_callback(); |
| 128 | PlayNextBuffer(); | 115 | PlayNextBuffer(cycles_late); |
| 129 | } | 116 | } |
| 130 | 117 | ||
| 131 | bool Stream::QueueBuffer(BufferPtr&& buffer) { | 118 | bool Stream::QueueBuffer(BufferPtr&& buffer) { |
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index e309d60fe..524376257 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h | |||
| @@ -90,10 +90,10 @@ public: | |||
| 90 | 90 | ||
| 91 | private: | 91 | private: |
| 92 | /// Plays the next queued buffer in the audio stream, starting playback if necessary | 92 | /// Plays the next queued buffer in the audio stream, starting playback if necessary |
| 93 | void PlayNextBuffer(); | 93 | void PlayNextBuffer(s64 cycles_late = 0); |
| 94 | 94 | ||
| 95 | /// Releases the actively playing buffer, signalling that it has been completed | 95 | /// Releases the actively playing buffer, signalling that it has been completed |
| 96 | void ReleaseActiveBuffer(); | 96 | void ReleaseActiveBuffer(s64 cycles_late = 0); |
| 97 | 97 | ||
| 98 | /// Gets the number of core cycles when the specified buffer will be released | 98 | /// Gets the number of core cycles when the specified buffer will be released |
| 99 | s64 GetBufferReleaseNS(const Buffer& buffer) const; | 99 | s64 GetBufferReleaseNS(const Buffer& buffer) const; |