Merge pull request #8878 from Kelebek1/remove_pause
Remove pause callbacks from coretiming
This commit is contained in:
		| @@ -47,16 +47,6 @@ AudioRenderer::ADSP::ADSP& AudioCore::GetADSP() { | |||||||
|     return *adsp; |     return *adsp; | ||||||
| } | } | ||||||
|  |  | ||||||
| void AudioCore::PauseSinks(const bool pausing) const { |  | ||||||
|     if (pausing) { |  | ||||||
|         output_sink->PauseStreams(); |  | ||||||
|         input_sink->PauseStreams(); |  | ||||||
|     } else { |  | ||||||
|         output_sink->UnpauseStreams(); |  | ||||||
|         input_sink->UnpauseStreams(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AudioCore::SetNVDECActive(bool active) { | void AudioCore::SetNVDECActive(bool active) { | ||||||
|     nvdec_active = active; |     nvdec_active = active; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -57,14 +57,6 @@ public: | |||||||
|      */ |      */ | ||||||
|     AudioRenderer::ADSP::ADSP& GetADSP(); |     AudioRenderer::ADSP::ADSP& GetADSP(); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Pause the sink. Called from the core. |  | ||||||
|      * |  | ||||||
|      * @param pausing - Is this pause due to an actual pause, or shutdown? |  | ||||||
|      *                  Unfortunately, shutdown also pauses streams, which can cause issues. |  | ||||||
|      */ |  | ||||||
|     void PauseSinks(bool pausing) const; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Toggle NVDEC state, used to avoid stall in playback. |      * Toggle NVDEC state, used to avoid stall in playback. | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -22,9 +22,7 @@ SystemManager::SystemManager(Core::System& core_) | |||||||
|       thread_event{Core::Timing::CreateEvent( |       thread_event{Core::Timing::CreateEvent( | ||||||
|           "AudioRendererSystemManager", [this](std::uintptr_t, s64 time, std::chrono::nanoseconds) { |           "AudioRendererSystemManager", [this](std::uintptr_t, s64 time, std::chrono::nanoseconds) { | ||||||
|               return ThreadFunc2(time); |               return ThreadFunc2(time); | ||||||
|           })} { |           })} {} | ||||||
|     core.CoreTiming().RegisterPauseCallback([this](bool paused) { PauseCallback(paused); }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| SystemManager::~SystemManager() { | SystemManager::~SystemManager() { | ||||||
|     Stop(); |     Stop(); | ||||||
| @@ -125,11 +123,4 @@ std::optional<std::chrono::nanoseconds> SystemManager::ThreadFunc2(s64 time) { | |||||||
|     return std::nullopt; |     return std::nullopt; | ||||||
| } | } | ||||||
|  |  | ||||||
| void SystemManager::PauseCallback(bool paused) { |  | ||||||
|     if (paused && core.IsPoweredOn() && core.IsShuttingDown()) { |  | ||||||
|         update.store(true); |  | ||||||
|         update.notify_all(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| } // namespace AudioCore::AudioRenderer | } // namespace AudioCore::AudioRenderer | ||||||
|   | |||||||
| @@ -73,13 +73,6 @@ private: | |||||||
|      */ |      */ | ||||||
|     std::optional<std::chrono::nanoseconds> ThreadFunc2(s64 time); |     std::optional<std::chrono::nanoseconds> ThreadFunc2(s64 time); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Callback from core timing when pausing, used to detect shutdowns and stop ThreadFunc. |  | ||||||
|      * |  | ||||||
|      * @param paused - Are we pausing or resuming? |  | ||||||
|      */ |  | ||||||
|     void PauseCallback(bool paused); |  | ||||||
|  |  | ||||||
|     enum class StreamState { |     enum class StreamState { | ||||||
|         Filling, |         Filling, | ||||||
|         Steady, |         Steady, | ||||||
| @@ -106,8 +99,6 @@ private: | |||||||
|     std::shared_ptr<Core::Timing::EventType> thread_event; |     std::shared_ptr<Core::Timing::EventType> thread_event; | ||||||
|     /// Atomic for main thread to wait on |     /// Atomic for main thread to wait on | ||||||
|     std::atomic<bool> update{}; |     std::atomic<bool> update{}; | ||||||
|     /// Current state of the streams |  | ||||||
|     StreamState state{StreamState::Filling}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace AudioCore::AudioRenderer | } // namespace AudioCore::AudioRenderer | ||||||
|   | |||||||
| @@ -129,20 +129,13 @@ public: | |||||||
|      *                 Default false. |      *                 Default false. | ||||||
|      */ |      */ | ||||||
|     void Start(bool resume = false) override { |     void Start(bool resume = false) override { | ||||||
|         if (!ctx) { |         if (!ctx || !paused) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (resume && was_playing) { |         paused = false; | ||||||
|             if (cubeb_stream_start(stream_backend) != CUBEB_OK) { |         if (cubeb_stream_start(stream_backend) != CUBEB_OK) { | ||||||
|                 LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream"); |             LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream"); | ||||||
|             } |  | ||||||
|             paused = false; |  | ||||||
|         } else if (!resume) { |  | ||||||
|             if (cubeb_stream_start(stream_backend) != CUBEB_OK) { |  | ||||||
|                 LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream"); |  | ||||||
|             } |  | ||||||
|             paused = false; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -151,16 +144,15 @@ public: | |||||||
|      */ |      */ | ||||||
|     void Stop() override { |     void Stop() override { | ||||||
|         Unstall(); |         Unstall(); | ||||||
|         if (!ctx) { |  | ||||||
|  |         if (!ctx || paused) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         paused = true; | ||||||
|         if (cubeb_stream_stop(stream_backend) != CUBEB_OK) { |         if (cubeb_stream_stop(stream_backend) != CUBEB_OK) { | ||||||
|             LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream"); |             LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         was_playing.store(!paused); |  | ||||||
|         paused = true; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| private: | private: | ||||||
| @@ -286,18 +278,6 @@ void CubebSink::CloseStreams() { | |||||||
|     sink_streams.clear(); |     sink_streams.clear(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CubebSink::PauseStreams() { |  | ||||||
|     for (auto& stream : sink_streams) { |  | ||||||
|         stream->Stop(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void CubebSink::UnpauseStreams() { |  | ||||||
|     for (auto& stream : sink_streams) { |  | ||||||
|         stream->Start(true); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| f32 CubebSink::GetDeviceVolume() const { | f32 CubebSink::GetDeviceVolume() const { | ||||||
|     if (sink_streams.empty()) { |     if (sink_streams.empty()) { | ||||||
|         return 1.0f; |         return 1.0f; | ||||||
|   | |||||||
| @@ -52,16 +52,6 @@ public: | |||||||
|      */ |      */ | ||||||
|     void CloseStreams() override; |     void CloseStreams() override; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Pause all streams. |  | ||||||
|      */ |  | ||||||
|     void PauseStreams() override; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Unpause all streams. |  | ||||||
|      */ |  | ||||||
|     void UnpauseStreams() override; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the device volume. Set from calls to the IAudioDevice service. |      * Get the device volume. Set from calls to the IAudioDevice service. | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -44,8 +44,6 @@ public: | |||||||
|  |  | ||||||
|     void CloseStream(SinkStream*) override {} |     void CloseStream(SinkStream*) override {} | ||||||
|     void CloseStreams() override {} |     void CloseStreams() override {} | ||||||
|     void PauseStreams() override {} |  | ||||||
|     void UnpauseStreams() override {} |  | ||||||
|     f32 GetDeviceVolume() const override { |     f32 GetDeviceVolume() const override { | ||||||
|         return 1.0f; |         return 1.0f; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -108,17 +108,12 @@ public: | |||||||
|      *                 Default false. |      *                 Default false. | ||||||
|      */ |      */ | ||||||
|     void Start(bool resume = false) override { |     void Start(bool resume = false) override { | ||||||
|         if (device == 0) { |         if (device == 0 || !paused) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (resume && was_playing) { |         paused = false; | ||||||
|             SDL_PauseAudioDevice(device, 0); |         SDL_PauseAudioDevice(device, 0); | ||||||
|             paused = false; |  | ||||||
|         } else if (!resume) { |  | ||||||
|             SDL_PauseAudioDevice(device, 0); |  | ||||||
|             paused = false; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -126,11 +121,11 @@ public: | |||||||
|      */ |      */ | ||||||
|     void Stop() override { |     void Stop() override { | ||||||
|         Unstall(); |         Unstall(); | ||||||
|         if (device == 0) { |         if (device == 0 || paused) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         SDL_PauseAudioDevice(device, 1); |  | ||||||
|         paused = true; |         paused = true; | ||||||
|  |         SDL_PauseAudioDevice(device, 1); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| private: | private: | ||||||
| @@ -207,18 +202,6 @@ void SDLSink::CloseStreams() { | |||||||
|     sink_streams.clear(); |     sink_streams.clear(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SDLSink::PauseStreams() { |  | ||||||
|     for (auto& stream : sink_streams) { |  | ||||||
|         stream->Stop(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void SDLSink::UnpauseStreams() { |  | ||||||
|     for (auto& stream : sink_streams) { |  | ||||||
|         stream->Start(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| f32 SDLSink::GetDeviceVolume() const { | f32 SDLSink::GetDeviceVolume() const { | ||||||
|     if (sink_streams.empty()) { |     if (sink_streams.empty()) { | ||||||
|         return 1.0f; |         return 1.0f; | ||||||
|   | |||||||
| @@ -50,16 +50,6 @@ public: | |||||||
|      */ |      */ | ||||||
|     void CloseStreams() override; |     void CloseStreams() override; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Pause all streams. |  | ||||||
|      */ |  | ||||||
|     void PauseStreams() override; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Unpause all streams. |  | ||||||
|      */ |  | ||||||
|     void UnpauseStreams() override; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the device volume. Set from calls to the IAudioDevice service. |      * Get the device volume. Set from calls to the IAudioDevice service. | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -39,16 +39,6 @@ public: | |||||||
|      */ |      */ | ||||||
|     virtual void CloseStreams() = 0; |     virtual void CloseStreams() = 0; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Pause all streams. |  | ||||||
|      */ |  | ||||||
|     virtual void PauseStreams() = 0; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Unpause all streams. |  | ||||||
|      */ |  | ||||||
|     virtual void UnpauseStreams() = 0; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Create a new sink stream, kept within this sink, with a pointer returned for use. |      * Create a new sink stream, kept within this sink, with a pointer returned for use. | ||||||
|      * Do not free the returned pointer. When done with the stream, call CloseStream on the sink. |      * Do not free the returned pointer. When done with the stream, call CloseStream on the sink. | ||||||
|   | |||||||
| @@ -143,6 +143,12 @@ void SinkStream::ProcessAudioIn(std::span<const s16> input_buffer, std::size_t n | |||||||
|     const std::size_t frame_size_bytes = frame_size * sizeof(s16); |     const std::size_t frame_size_bytes = frame_size * sizeof(s16); | ||||||
|     size_t frames_written{0}; |     size_t frames_written{0}; | ||||||
|  |  | ||||||
|  |     // If we're paused or going to shut down, we don't want to consume buffers as coretiming is | ||||||
|  |     // paused and we'll desync, so just return. | ||||||
|  |     if (system.IsPaused() || system.IsShuttingDown()) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (queued_buffers > max_queue_size) { |     if (queued_buffers > max_queue_size) { | ||||||
|         Stall(); |         Stall(); | ||||||
|     } |     } | ||||||
| @@ -193,6 +199,16 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz | |||||||
|     const std::size_t frame_size_bytes = frame_size * sizeof(s16); |     const std::size_t frame_size_bytes = frame_size * sizeof(s16); | ||||||
|     size_t frames_written{0}; |     size_t frames_written{0}; | ||||||
|  |  | ||||||
|  |     // If we're paused or going to shut down, we don't want to consume buffers as coretiming is | ||||||
|  |     // paused and we'll desync, so just play silence. | ||||||
|  |     if (system.IsPaused() || system.IsShuttingDown()) { | ||||||
|  |         constexpr std::array<s16, 6> silence{}; | ||||||
|  |         for (size_t i = frames_written; i < num_frames; i++) { | ||||||
|  |             std::memcpy(&output_buffer[i * frame_size], &silence[0], frame_size_bytes); | ||||||
|  |         } | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Due to many frames being queued up with nvdec (5 frames or so?), a lot of buffers also get |     // Due to many frames being queued up with nvdec (5 frames or so?), a lot of buffers also get | ||||||
|     // queued up (30+) but not all at once, which causes constant stalling here, so just let the |     // queued up (30+) but not all at once, which causes constant stalling here, so just let the | ||||||
|     // video play out without attempting to stall. |     // video play out without attempting to stall. | ||||||
|   | |||||||
| @@ -220,8 +220,6 @@ protected: | |||||||
|     u32 device_channels{2}; |     u32 device_channels{2}; | ||||||
|     /// Is this stream currently paused? |     /// Is this stream currently paused? | ||||||
|     std::atomic<bool> paused{true}; |     std::atomic<bool> paused{true}; | ||||||
|     /// Was this stream previously playing? |  | ||||||
|     std::atomic<bool> was_playing{false}; |  | ||||||
|     /// Name of this stream |     /// Name of this stream | ||||||
|     std::string name{}; |     std::string name{}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -141,8 +141,6 @@ struct System::Impl { | |||||||
|         core_timing.SyncPause(false); |         core_timing.SyncPause(false); | ||||||
|         is_paused = false; |         is_paused = false; | ||||||
|  |  | ||||||
|         audio_core->PauseSinks(false); |  | ||||||
|  |  | ||||||
|         return status; |         return status; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -150,8 +148,6 @@ struct System::Impl { | |||||||
|         std::unique_lock<std::mutex> lk(suspend_guard); |         std::unique_lock<std::mutex> lk(suspend_guard); | ||||||
|         status = SystemResultStatus::Success; |         status = SystemResultStatus::Success; | ||||||
|  |  | ||||||
|         audio_core->PauseSinks(true); |  | ||||||
|  |  | ||||||
|         core_timing.SyncPause(true); |         core_timing.SyncPause(true); | ||||||
|         kernel.Suspend(true); |         kernel.Suspend(true); | ||||||
|         is_paused = true; |         is_paused = true; | ||||||
|   | |||||||
| @@ -73,7 +73,6 @@ void CoreTiming::Shutdown() { | |||||||
|     if (timer_thread) { |     if (timer_thread) { | ||||||
|         timer_thread->join(); |         timer_thread->join(); | ||||||
|     } |     } | ||||||
|     pause_callbacks.clear(); |  | ||||||
|     ClearPendingEvents(); |     ClearPendingEvents(); | ||||||
|     timer_thread.reset(); |     timer_thread.reset(); | ||||||
|     has_started = false; |     has_started = false; | ||||||
| @@ -86,10 +85,6 @@ void CoreTiming::Pause(bool is_paused) { | |||||||
|     if (!is_paused) { |     if (!is_paused) { | ||||||
|         pause_end_time = GetGlobalTimeNs().count(); |         pause_end_time = GetGlobalTimeNs().count(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     for (auto& cb : pause_callbacks) { |  | ||||||
|         cb(is_paused); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void CoreTiming::SyncPause(bool is_paused) { | void CoreTiming::SyncPause(bool is_paused) { | ||||||
| @@ -110,10 +105,6 @@ void CoreTiming::SyncPause(bool is_paused) { | |||||||
|     if (!is_paused) { |     if (!is_paused) { | ||||||
|         pause_end_time = GetGlobalTimeNs().count(); |         pause_end_time = GetGlobalTimeNs().count(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     for (auto& cb : pause_callbacks) { |  | ||||||
|         cb(is_paused); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CoreTiming::IsRunning() const { | bool CoreTiming::IsRunning() const { | ||||||
| @@ -219,11 +210,6 @@ void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void CoreTiming::RegisterPauseCallback(PauseCallback&& callback) { |  | ||||||
|     std::scoped_lock lock{basic_lock}; |  | ||||||
|     pause_callbacks.emplace_back(std::move(callback)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| std::optional<s64> CoreTiming::Advance() { | std::optional<s64> CoreTiming::Advance() { | ||||||
|     std::scoped_lock lock{advance_lock, basic_lock}; |     std::scoped_lock lock{advance_lock, basic_lock}; | ||||||
|     global_timer = GetGlobalTimeNs().count(); |     global_timer = GetGlobalTimeNs().count(); | ||||||
|   | |||||||
| @@ -22,7 +22,6 @@ namespace Core::Timing { | |||||||
| /// A callback that may be scheduled for a particular core timing event. | /// A callback that may be scheduled for a particular core timing event. | ||||||
| using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>( | using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>( | ||||||
|     std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)>; |     std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)>; | ||||||
| using PauseCallback = std::function<void(bool paused)>; |  | ||||||
|  |  | ||||||
| /// Contains the characteristics of a particular event. | /// Contains the characteristics of a particular event. | ||||||
| struct EventType { | struct EventType { | ||||||
| @@ -134,9 +133,6 @@ public: | |||||||
|     /// Checks for events manually and returns time in nanoseconds for next event, threadsafe. |     /// Checks for events manually and returns time in nanoseconds for next event, threadsafe. | ||||||
|     std::optional<s64> Advance(); |     std::optional<s64> Advance(); | ||||||
|  |  | ||||||
|     /// Register a callback function to be called when coretiming pauses. |  | ||||||
|     void RegisterPauseCallback(PauseCallback&& callback); |  | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     struct Event; |     struct Event; | ||||||
|  |  | ||||||
| @@ -176,8 +172,6 @@ private: | |||||||
|     /// Cycle timing |     /// Cycle timing | ||||||
|     u64 ticks{}; |     u64 ticks{}; | ||||||
|     s64 downcount{}; |     s64 downcount{}; | ||||||
|  |  | ||||||
|     std::vector<PauseCallback> pause_callbacks{}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /// Creates a core timing event with the given name and callback. | /// Creates a core timing event with the given name and callback. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user