summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Kelebek12022-09-10 21:14:03 +0100
committerGravatar Kelebek12022-09-13 13:20:35 +0100
commite93e898df528d013e2e0cfeba22e2b6d76bf99b6 (patch)
treeab921a035ce71311c126a1af7cb2bbcbfef6d024
parentMerge pull request #8842 from Kelebek1/AudOut (diff)
downloadyuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.tar.gz
yuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.tar.xz
yuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.zip
Remove pause callbacks from coretiming
-rw-r--r--src/audio_core/audio_core.cpp10
-rw-r--r--src/audio_core/audio_core.h8
-rw-r--r--src/audio_core/renderer/system_manager.cpp11
-rw-r--r--src/audio_core/renderer/system_manager.h9
-rw-r--r--src/audio_core/sink/cubeb_sink.cpp34
-rw-r--r--src/audio_core/sink/cubeb_sink.h10
-rw-r--r--src/audio_core/sink/null_sink.h2
-rw-r--r--src/audio_core/sink/sdl2_sink.cpp27
-rw-r--r--src/audio_core/sink/sdl2_sink.h10
-rw-r--r--src/audio_core/sink/sink.h10
-rw-r--r--src/audio_core/sink/sink_stream.cpp16
-rw-r--r--src/audio_core/sink/sink_stream.h2
-rw-r--r--src/core/core.cpp4
-rw-r--r--src/core/core_timing.cpp14
-rw-r--r--src/core/core_timing.h6
15 files changed, 29 insertions, 144 deletions
diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp
index 9feec1829..c845330cd 100644
--- a/src/audio_core/audio_core.cpp
+++ b/src/audio_core/audio_core.cpp
@@ -47,16 +47,6 @@ AudioRenderer::ADSP::ADSP& AudioCore::GetADSP() {
47 return *adsp; 47 return *adsp;
48} 48}
49 49
50void AudioCore::PauseSinks(const bool pausing) const {
51 if (pausing) {
52 output_sink->PauseStreams();
53 input_sink->PauseStreams();
54 } else {
55 output_sink->UnpauseStreams();
56 input_sink->UnpauseStreams();
57 }
58}
59
60void AudioCore::SetNVDECActive(bool active) { 50void AudioCore::SetNVDECActive(bool active) {
61 nvdec_active = active; 51 nvdec_active = active;
62} 52}
diff --git a/src/audio_core/audio_core.h b/src/audio_core/audio_core.h
index ac9afefaa..c0a11e6b1 100644
--- a/src/audio_core/audio_core.h
+++ b/src/audio_core/audio_core.h
@@ -58,14 +58,6 @@ public:
58 AudioRenderer::ADSP::ADSP& GetADSP(); 58 AudioRenderer::ADSP::ADSP& GetADSP();
59 59
60 /** 60 /**
61 * Pause the sink. Called from the core.
62 *
63 * @param pausing - Is this pause due to an actual pause, or shutdown?
64 * Unfortunately, shutdown also pauses streams, which can cause issues.
65 */
66 void PauseSinks(bool pausing) const;
67
68 /**
69 * Toggle NVDEC state, used to avoid stall in playback. 61 * Toggle NVDEC state, used to avoid stall in playback.
70 * 62 *
71 * @param active - Set true if nvdec is active, otherwise false. 63 * @param active - Set true if nvdec is active, otherwise false.
diff --git a/src/audio_core/renderer/system_manager.cpp b/src/audio_core/renderer/system_manager.cpp
index bc2dd9e6e..9c1331e19 100644
--- a/src/audio_core/renderer/system_manager.cpp
+++ b/src/audio_core/renderer/system_manager.cpp
@@ -22,9 +22,7 @@ SystemManager::SystemManager(Core::System& core_)
22 thread_event{Core::Timing::CreateEvent( 22 thread_event{Core::Timing::CreateEvent(
23 "AudioRendererSystemManager", [this](std::uintptr_t, s64 time, std::chrono::nanoseconds) { 23 "AudioRendererSystemManager", [this](std::uintptr_t, s64 time, std::chrono::nanoseconds) {
24 return ThreadFunc2(time); 24 return ThreadFunc2(time);
25 })} { 25 })} {}
26 core.CoreTiming().RegisterPauseCallback([this](bool paused) { PauseCallback(paused); });
27}
28 26
29SystemManager::~SystemManager() { 27SystemManager::~SystemManager() {
30 Stop(); 28 Stop();
@@ -125,11 +123,4 @@ std::optional<std::chrono::nanoseconds> SystemManager::ThreadFunc2(s64 time) {
125 return std::nullopt; 123 return std::nullopt;
126} 124}
127 125
128void SystemManager::PauseCallback(bool paused) {
129 if (paused && core.IsPoweredOn() && core.IsShuttingDown()) {
130 update.store(true);
131 update.notify_all();
132 }
133}
134
135} // namespace AudioCore::AudioRenderer 126} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/system_manager.h b/src/audio_core/renderer/system_manager.h
index 1291e9e0e..81457a3a1 100644
--- a/src/audio_core/renderer/system_manager.h
+++ b/src/audio_core/renderer/system_manager.h
@@ -73,13 +73,6 @@ private:
73 */ 73 */
74 std::optional<std::chrono::nanoseconds> ThreadFunc2(s64 time); 74 std::optional<std::chrono::nanoseconds> ThreadFunc2(s64 time);
75 75
76 /**
77 * Callback from core timing when pausing, used to detect shutdowns and stop ThreadFunc.
78 *
79 * @param paused - Are we pausing or resuming?
80 */
81 void PauseCallback(bool paused);
82
83 enum class StreamState { 76 enum class StreamState {
84 Filling, 77 Filling,
85 Steady, 78 Steady,
@@ -106,8 +99,6 @@ private:
106 std::shared_ptr<Core::Timing::EventType> thread_event; 99 std::shared_ptr<Core::Timing::EventType> thread_event;
107 /// Atomic for main thread to wait on 100 /// Atomic for main thread to wait on
108 std::atomic<bool> update{}; 101 std::atomic<bool> update{};
109 /// Current state of the streams
110 StreamState state{StreamState::Filling};
111}; 102};
112 103
113} // namespace AudioCore::AudioRenderer 104} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp
index 9ae043611..36b115ad6 100644
--- a/src/audio_core/sink/cubeb_sink.cpp
+++ b/src/audio_core/sink/cubeb_sink.cpp
@@ -129,20 +129,13 @@ public:
129 * Default false. 129 * Default false.
130 */ 130 */
131 void Start(bool resume = false) override { 131 void Start(bool resume = false) override {
132 if (!ctx) { 132 if (!ctx || !paused) {
133 return; 133 return;
134 } 134 }
135 135
136 if (resume && was_playing) { 136 paused = false;
137 if (cubeb_stream_start(stream_backend) != CUBEB_OK) { 137 if (cubeb_stream_start(stream_backend) != CUBEB_OK) {
138 LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream"); 138 LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream");
139 }
140 paused = false;
141 } else if (!resume) {
142 if (cubeb_stream_start(stream_backend) != CUBEB_OK) {
143 LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream");
144 }
145 paused = false;
146 } 139 }
147 } 140 }
148 141
@@ -151,16 +144,15 @@ public:
151 */ 144 */
152 void Stop() override { 145 void Stop() override {
153 Unstall(); 146 Unstall();
154 if (!ctx) { 147
148 if (!ctx || paused) {
155 return; 149 return;
156 } 150 }
157 151
152 paused = true;
158 if (cubeb_stream_stop(stream_backend) != CUBEB_OK) { 153 if (cubeb_stream_stop(stream_backend) != CUBEB_OK) {
159 LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream"); 154 LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream");
160 } 155 }
161
162 was_playing.store(!paused);
163 paused = true;
164 } 156 }
165 157
166private: 158private:
@@ -286,18 +278,6 @@ void CubebSink::CloseStreams() {
286 sink_streams.clear(); 278 sink_streams.clear();
287} 279}
288 280
289void CubebSink::PauseStreams() {
290 for (auto& stream : sink_streams) {
291 stream->Stop();
292 }
293}
294
295void CubebSink::UnpauseStreams() {
296 for (auto& stream : sink_streams) {
297 stream->Start(true);
298 }
299}
300
301f32 CubebSink::GetDeviceVolume() const { 281f32 CubebSink::GetDeviceVolume() const {
302 if (sink_streams.empty()) { 282 if (sink_streams.empty()) {
303 return 1.0f; 283 return 1.0f;
diff --git a/src/audio_core/sink/cubeb_sink.h b/src/audio_core/sink/cubeb_sink.h
index 91a6480fa..d98fc0866 100644
--- a/src/audio_core/sink/cubeb_sink.h
+++ b/src/audio_core/sink/cubeb_sink.h
@@ -54,16 +54,6 @@ public:
54 void CloseStreams() override; 54 void CloseStreams() override;
55 55
56 /** 56 /**
57 * Pause all streams.
58 */
59 void PauseStreams() override;
60
61 /**
62 * Unpause all streams.
63 */
64 void UnpauseStreams() override;
65
66 /**
67 * Get the device volume. Set from calls to the IAudioDevice service. 57 * Get the device volume. Set from calls to the IAudioDevice service.
68 * 58 *
69 * @return Volume of the device. 59 * @return Volume of the device.
diff --git a/src/audio_core/sink/null_sink.h b/src/audio_core/sink/null_sink.h
index eab9c3a0c..1215d3cd2 100644
--- a/src/audio_core/sink/null_sink.h
+++ b/src/audio_core/sink/null_sink.h
@@ -44,8 +44,6 @@ public:
44 44
45 void CloseStream(SinkStream*) override {} 45 void CloseStream(SinkStream*) override {}
46 void CloseStreams() override {} 46 void CloseStreams() override {}
47 void PauseStreams() override {}
48 void UnpauseStreams() override {}
49 f32 GetDeviceVolume() const override { 47 f32 GetDeviceVolume() const override {
50 return 1.0f; 48 return 1.0f;
51 } 49 }
diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp
index 7ee1dd7cd..1bd001b94 100644
--- a/src/audio_core/sink/sdl2_sink.cpp
+++ b/src/audio_core/sink/sdl2_sink.cpp
@@ -108,17 +108,12 @@ public:
108 * Default false. 108 * Default false.
109 */ 109 */
110 void Start(bool resume = false) override { 110 void Start(bool resume = false) override {
111 if (device == 0) { 111 if (device == 0 || !paused) {
112 return; 112 return;
113 } 113 }
114 114
115 if (resume && was_playing) { 115 paused = false;
116 SDL_PauseAudioDevice(device, 0); 116 SDL_PauseAudioDevice(device, 0);
117 paused = false;
118 } else if (!resume) {
119 SDL_PauseAudioDevice(device, 0);
120 paused = false;
121 }
122 } 117 }
123 118
124 /** 119 /**
@@ -126,11 +121,11 @@ public:
126 */ 121 */
127 void Stop() override { 122 void Stop() override {
128 Unstall(); 123 Unstall();
129 if (device == 0) { 124 if (device == 0 || paused) {
130 return; 125 return;
131 } 126 }
132 SDL_PauseAudioDevice(device, 1);
133 paused = true; 127 paused = true;
128 SDL_PauseAudioDevice(device, 1);
134 } 129 }
135 130
136private: 131private:
@@ -207,18 +202,6 @@ void SDLSink::CloseStreams() {
207 sink_streams.clear(); 202 sink_streams.clear();
208} 203}
209 204
210void SDLSink::PauseStreams() {
211 for (auto& stream : sink_streams) {
212 stream->Stop();
213 }
214}
215
216void SDLSink::UnpauseStreams() {
217 for (auto& stream : sink_streams) {
218 stream->Start();
219 }
220}
221
222f32 SDLSink::GetDeviceVolume() const { 205f32 SDLSink::GetDeviceVolume() const {
223 if (sink_streams.empty()) { 206 if (sink_streams.empty()) {
224 return 1.0f; 207 return 1.0f;
diff --git a/src/audio_core/sink/sdl2_sink.h b/src/audio_core/sink/sdl2_sink.h
index 57de9b6c2..9e76dde4f 100644
--- a/src/audio_core/sink/sdl2_sink.h
+++ b/src/audio_core/sink/sdl2_sink.h
@@ -52,16 +52,6 @@ public:
52 void CloseStreams() override; 52 void CloseStreams() override;
53 53
54 /** 54 /**
55 * Pause all streams.
56 */
57 void PauseStreams() override;
58
59 /**
60 * Unpause all streams.
61 */
62 void UnpauseStreams() override;
63
64 /**
65 * Get the device volume. Set from calls to the IAudioDevice service. 55 * Get the device volume. Set from calls to the IAudioDevice service.
66 * 56 *
67 * @return Volume of the device. 57 * @return Volume of the device.
diff --git a/src/audio_core/sink/sink.h b/src/audio_core/sink/sink.h
index 43d99b62e..61e3d80cc 100644
--- a/src/audio_core/sink/sink.h
+++ b/src/audio_core/sink/sink.h
@@ -40,16 +40,6 @@ public:
40 virtual void CloseStreams() = 0; 40 virtual void CloseStreams() = 0;
41 41
42 /** 42 /**
43 * Pause all streams.
44 */
45 virtual void PauseStreams() = 0;
46
47 /**
48 * Unpause all streams.
49 */
50 virtual void UnpauseStreams() = 0;
51
52 /**
53 * Create a new sink stream, kept within this sink, with a pointer returned for use. 43 * Create a new sink stream, kept within this sink, with a pointer returned for use.
54 * Do not free the returned pointer. When done with the stream, call CloseStream on the sink. 44 * Do not free the returned pointer. When done with the stream, call CloseStream on the sink.
55 * 45 *
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp
index 24636e512..59a8d69f0 100644
--- a/src/audio_core/sink/sink_stream.cpp
+++ b/src/audio_core/sink/sink_stream.cpp
@@ -145,6 +145,12 @@ void SinkStream::ProcessAudioIn(std::span<const s16> input_buffer, std::size_t n
145 const std::size_t frame_size_bytes = frame_size * sizeof(s16); 145 const std::size_t frame_size_bytes = frame_size * sizeof(s16);
146 size_t frames_written{0}; 146 size_t frames_written{0};
147 147
148 // If we're paused or going to shut down, we don't want to consume buffers as coretiming is
149 // paused and we'll desync, so just return.
150 if (system.IsPaused() || system.IsShuttingDown()) {
151 return;
152 }
153
148 if (queued_buffers > max_queue_size) { 154 if (queued_buffers > max_queue_size) {
149 Stall(); 155 Stall();
150 } 156 }
@@ -195,6 +201,16 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
195 const std::size_t frame_size_bytes = frame_size * sizeof(s16); 201 const std::size_t frame_size_bytes = frame_size * sizeof(s16);
196 size_t frames_written{0}; 202 size_t frames_written{0};
197 203
204 // If we're paused or going to shut down, we don't want to consume buffers as coretiming is
205 // paused and we'll desync, so just play silence.
206 if (system.IsPaused() || system.IsShuttingDown()) {
207 constexpr std::array<s16, 6> silence{};
208 for (size_t i = frames_written; i < num_frames; i++) {
209 std::memcpy(&output_buffer[i * frame_size], &silence[0], frame_size_bytes);
210 }
211 return;
212 }
213
198 // Due to many frames being queued up with nvdec (5 frames or so?), a lot of buffers also get 214 // Due to many frames being queued up with nvdec (5 frames or so?), a lot of buffers also get
199 // queued up (30+) but not all at once, which causes constant stalling here, so just let the 215 // queued up (30+) but not all at once, which causes constant stalling here, so just let the
200 // video play out without attempting to stall. 216 // video play out without attempting to stall.
diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h
index db7cff45e..9aada54f1 100644
--- a/src/audio_core/sink/sink_stream.h
+++ b/src/audio_core/sink/sink_stream.h
@@ -220,8 +220,6 @@ protected:
220 u32 device_channels{2}; 220 u32 device_channels{2};
221 /// Is this stream currently paused? 221 /// Is this stream currently paused?
222 std::atomic<bool> paused{true}; 222 std::atomic<bool> paused{true};
223 /// Was this stream previously playing?
224 std::atomic<bool> was_playing{false};
225 /// Name of this stream 223 /// Name of this stream
226 std::string name{}; 224 std::string name{};
227 225
diff --git a/src/core/core.cpp b/src/core/core.cpp
index e651ce100..121092868 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -141,8 +141,6 @@ struct System::Impl {
141 core_timing.SyncPause(false); 141 core_timing.SyncPause(false);
142 is_paused = false; 142 is_paused = false;
143 143
144 audio_core->PauseSinks(false);
145
146 return status; 144 return status;
147 } 145 }
148 146
@@ -150,8 +148,6 @@ struct System::Impl {
150 std::unique_lock<std::mutex> lk(suspend_guard); 148 std::unique_lock<std::mutex> lk(suspend_guard);
151 status = SystemResultStatus::Success; 149 status = SystemResultStatus::Success;
152 150
153 audio_core->PauseSinks(true);
154
155 core_timing.SyncPause(true); 151 core_timing.SyncPause(true);
156 kernel.Suspend(true); 152 kernel.Suspend(true);
157 is_paused = true; 153 is_paused = true;
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 2dbb99c8b..5375a5d59 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -73,7 +73,6 @@ void CoreTiming::Shutdown() {
73 if (timer_thread) { 73 if (timer_thread) {
74 timer_thread->join(); 74 timer_thread->join();
75 } 75 }
76 pause_callbacks.clear();
77 ClearPendingEvents(); 76 ClearPendingEvents();
78 timer_thread.reset(); 77 timer_thread.reset();
79 has_started = false; 78 has_started = false;
@@ -86,10 +85,6 @@ void CoreTiming::Pause(bool is_paused) {
86 if (!is_paused) { 85 if (!is_paused) {
87 pause_end_time = GetGlobalTimeNs().count(); 86 pause_end_time = GetGlobalTimeNs().count();
88 } 87 }
89
90 for (auto& cb : pause_callbacks) {
91 cb(is_paused);
92 }
93} 88}
94 89
95void CoreTiming::SyncPause(bool is_paused) { 90void CoreTiming::SyncPause(bool is_paused) {
@@ -110,10 +105,6 @@ void CoreTiming::SyncPause(bool is_paused) {
110 if (!is_paused) { 105 if (!is_paused) {
111 pause_end_time = GetGlobalTimeNs().count(); 106 pause_end_time = GetGlobalTimeNs().count();
112 } 107 }
113
114 for (auto& cb : pause_callbacks) {
115 cb(is_paused);
116 }
117} 108}
118 109
119bool CoreTiming::IsRunning() const { 110bool CoreTiming::IsRunning() const {
@@ -219,11 +210,6 @@ void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
219 } 210 }
220} 211}
221 212
222void CoreTiming::RegisterPauseCallback(PauseCallback&& callback) {
223 std::scoped_lock lock{basic_lock};
224 pause_callbacks.emplace_back(std::move(callback));
225}
226
227std::optional<s64> CoreTiming::Advance() { 213std::optional<s64> CoreTiming::Advance() {
228 std::scoped_lock lock{advance_lock, basic_lock}; 214 std::scoped_lock lock{advance_lock, basic_lock};
229 global_timer = GetGlobalTimeNs().count(); 215 global_timer = GetGlobalTimeNs().count();
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 6aa3ae923..3259397b2 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -22,7 +22,6 @@ namespace Core::Timing {
22/// A callback that may be scheduled for a particular core timing event. 22/// A callback that may be scheduled for a particular core timing event.
23using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>( 23using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>(
24 std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)>; 24 std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)>;
25using PauseCallback = std::function<void(bool paused)>;
26 25
27/// Contains the characteristics of a particular event. 26/// Contains the characteristics of a particular event.
28struct EventType { 27struct EventType {
@@ -134,9 +133,6 @@ public:
134 /// Checks for events manually and returns time in nanoseconds for next event, threadsafe. 133 /// Checks for events manually and returns time in nanoseconds for next event, threadsafe.
135 std::optional<s64> Advance(); 134 std::optional<s64> Advance();
136 135
137 /// Register a callback function to be called when coretiming pauses.
138 void RegisterPauseCallback(PauseCallback&& callback);
139
140private: 136private:
141 struct Event; 137 struct Event;
142 138
@@ -176,8 +172,6 @@ private:
176 /// Cycle timing 172 /// Cycle timing
177 u64 ticks{}; 173 u64 ticks{};
178 s64 downcount{}; 174 s64 downcount{};
179
180 std::vector<PauseCallback> pause_callbacks{};
181}; 175};
182 176
183/// Creates a core timing event with the given name and callback. 177/// Creates a core timing event with the given name and callback.