diff options
-rw-r--r-- | src/audio_core/audio_core.cpp | 10 | ||||
-rw-r--r-- | src/audio_core/audio_core.h | 8 | ||||
-rw-r--r-- | src/audio_core/renderer/system_manager.cpp | 11 | ||||
-rw-r--r-- | src/audio_core/renderer/system_manager.h | 9 | ||||
-rw-r--r-- | src/audio_core/sink/cubeb_sink.cpp | 34 | ||||
-rw-r--r-- | src/audio_core/sink/cubeb_sink.h | 10 | ||||
-rw-r--r-- | src/audio_core/sink/null_sink.h | 2 | ||||
-rw-r--r-- | src/audio_core/sink/sdl2_sink.cpp | 27 | ||||
-rw-r--r-- | src/audio_core/sink/sdl2_sink.h | 10 | ||||
-rw-r--r-- | src/audio_core/sink/sink.h | 10 | ||||
-rw-r--r-- | src/audio_core/sink/sink_stream.cpp | 16 | ||||
-rw-r--r-- | src/audio_core/sink/sink_stream.h | 2 | ||||
-rw-r--r-- | src/core/core.cpp | 4 | ||||
-rw-r--r-- | src/core/core_timing.cpp | 14 | ||||
-rw-r--r-- | src/core/core_timing.h | 6 |
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() { 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) { nvdec_active = active; } 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: 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. * * @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_) thread_event{Core::Timing::CreateEvent( "AudioRendererSystemManager", [this](std::uintptr_t, s64 time, std::chrono::nanoseconds) { return ThreadFunc2(time); - })} { - core.CoreTiming().RegisterPauseCallback([this](bool paused) { PauseCallback(paused); }); -} + })} {} SystemManager::~SystemManager() { Stop(); @@ -125,11 +123,4 @@ std::optional<std::chrono::nanoseconds> SystemManager::ThreadFunc2(s64 time) { return std::nullopt; } -void SystemManager::PauseCallback(bool paused) { - if (paused && core.IsPoweredOn() && core.IsShuttingDown()) { - update.store(true); - update.notify_all(); - } -} - } // 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: */ 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 { Filling, Steady, @@ -106,8 +99,6 @@ private: std::shared_ptr<Core::Timing::EventType> thread_event; /// Atomic for main thread to wait on std::atomic<bool> update{}; - /// Current state of the streams - StreamState state{StreamState::Filling}; }; } // 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: * Default false. */ void Start(bool resume = false) override { - if (!ctx) { + if (!ctx || !paused) { return; } - if (resume && was_playing) { - if (cubeb_stream_start(stream_backend) != CUBEB_OK) { - 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; + paused = false; + if (cubeb_stream_start(stream_backend) != CUBEB_OK) { + LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream"); } } @@ -151,16 +144,15 @@ public: */ void Stop() override { Unstall(); - if (!ctx) { + + if (!ctx || paused) { return; } + paused = true; if (cubeb_stream_stop(stream_backend) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream"); } - - was_playing.store(!paused); - paused = true; } private: @@ -286,18 +278,6 @@ void CubebSink::CloseStreams() { 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 { if (sink_streams.empty()) { 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: 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. * * @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: void CloseStream(SinkStream*) override {} void CloseStreams() override {} - void PauseStreams() override {} - void UnpauseStreams() override {} f32 GetDeviceVolume() const override { return 1.0f; } 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: * Default false. */ void Start(bool resume = false) override { - if (device == 0) { + if (device == 0 || !paused) { return; } - if (resume && was_playing) { - SDL_PauseAudioDevice(device, 0); - paused = false; - } else if (!resume) { - SDL_PauseAudioDevice(device, 0); - paused = false; - } + paused = false; + SDL_PauseAudioDevice(device, 0); } /** @@ -126,11 +121,11 @@ public: */ void Stop() override { Unstall(); - if (device == 0) { + if (device == 0 || paused) { return; } - SDL_PauseAudioDevice(device, 1); paused = true; + SDL_PauseAudioDevice(device, 1); } private: @@ -207,18 +202,6 @@ void SDLSink::CloseStreams() { 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 { if (sink_streams.empty()) { 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: 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. * * @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: 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. * Do not free the returned pointer. When done with the stream, call CloseStream on the sink. * 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 const std::size_t frame_size_bytes = frame_size * sizeof(s16); 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) { Stall(); } @@ -195,6 +201,16 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz const std::size_t frame_size_bytes = frame_size * sizeof(s16); 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 // queued up (30+) but not all at once, which causes constant stalling here, so just let the // 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: u32 device_channels{2}; /// Is this stream currently paused? std::atomic<bool> paused{true}; - /// Was this stream previously playing? - std::atomic<bool> was_playing{false}; /// Name of this stream std::string name{}; 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 { core_timing.SyncPause(false); is_paused = false; - audio_core->PauseSinks(false); - return status; } @@ -150,8 +148,6 @@ struct System::Impl { std::unique_lock<std::mutex> lk(suspend_guard); status = SystemResultStatus::Success; - audio_core->PauseSinks(true); - core_timing.SyncPause(true); kernel.Suspend(true); 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() { if (timer_thread) { timer_thread->join(); } - pause_callbacks.clear(); ClearPendingEvents(); timer_thread.reset(); has_started = false; @@ -86,10 +85,6 @@ void CoreTiming::Pause(bool is_paused) { if (!is_paused) { pause_end_time = GetGlobalTimeNs().count(); } - - for (auto& cb : pause_callbacks) { - cb(is_paused); - } } void CoreTiming::SyncPause(bool is_paused) { @@ -110,10 +105,6 @@ void CoreTiming::SyncPause(bool is_paused) { if (!is_paused) { pause_end_time = GetGlobalTimeNs().count(); } - - for (auto& cb : pause_callbacks) { - cb(is_paused); - } } 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::scoped_lock lock{advance_lock, basic_lock}; 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 { /// A callback that may be scheduled for a particular core timing event. using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>( 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. struct EventType { @@ -134,9 +133,6 @@ public: /// Checks for events manually and returns time in nanoseconds for next event, threadsafe. std::optional<s64> Advance(); - /// Register a callback function to be called when coretiming pauses. - void RegisterPauseCallback(PauseCallback&& callback); - private: struct Event; @@ -176,8 +172,6 @@ private: /// Cycle timing u64 ticks{}; s64 downcount{}; - - std::vector<PauseCallback> pause_callbacks{}; }; /// Creates a core timing event with the given name and callback. |