summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKelebek1 <eeeedddccc@hotmail.co.uk>2022-09-10 22:14:03 +0200
committerKelebek1 <eeeedddccc@hotmail.co.uk>2022-09-13 14:20:35 +0200
commite93e898df528d013e2e0cfeba22e2b6d76bf99b6 (patch)
treeab921a035ce71311c126a1af7cb2bbcbfef6d024
parentMerge pull request #8842 from Kelebek1/AudOut (diff)
downloadyuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.tar
yuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.tar.gz
yuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.tar.bz2
yuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.tar.lz
yuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.tar.xz
yuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.tar.zst
yuzu-e93e898df528d013e2e0cfeba22e2b6d76bf99b6.zip
-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() {
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.