diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp
index d42249ebd..8e19ec0c4 100644
--- a/src/audio_core/audio_core.cpp
+++ b/src/audio_core/audio_core.cpp
@@ -71,6 +71,10 @@ void SelectSink(std::string sink_id) {
     DSP::HLE::SetSink(iter->factory());
 }
 
+void EnableStretching(bool enable) {
+    DSP::HLE::EnableStretching(enable);
+}
+
 void Shutdown() {
     CoreTiming::UnscheduleEvent(tick_event, 0);
     DSP::HLE::Shutdown();
diff --git a/src/audio_core/audio_core.h b/src/audio_core/audio_core.h
index f618361f3..7e678aba5 100644
--- a/src/audio_core/audio_core.h
+++ b/src/audio_core/audio_core.h
@@ -23,6 +23,9 @@ void AddAddressSpace(Kernel::VMManager& vm_manager);
 /// Select the sink to use based on sink id.
 void SelectSink(std::string sink_id);
 
+/// Enable/Disable stretching.
+void EnableStretching(bool enable);
+
 /// Shutdown Audio Core
 void Shutdown();
 
diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp
index a195bc74c..0cddeb82a 100644
--- a/src/audio_core/hle/dsp.cpp
+++ b/src/audio_core/hle/dsp.cpp
@@ -85,13 +85,45 @@ static StereoFrame16 GenerateCurrentFrame() {
 
 // Audio output
 
+static bool perform_time_stretching = true;
 static std::unique_ptr<AudioCore::Sink> sink;
 static AudioCore::TimeStretcher time_stretcher;
 
+static void FlushResidualStretcherAudio() {
+    time_stretcher.Flush();
+    while (true) {
+        std::vector<s16> residual_audio = time_stretcher.Process(sink->SamplesInQueue());
+        if (residual_audio.empty())
+            break;
+        sink->EnqueueSamples(residual_audio.data(), residual_audio.size() / 2);
+    }
+}
+
 static void OutputCurrentFrame(const StereoFrame16& frame) {
-    time_stretcher.AddSamples(&frame[0][0], frame.size());
-    std::vector<s16> stretched_samples = time_stretcher.Process(sink->SamplesInQueue());
-    sink->EnqueueSamples(stretched_samples.data(), stretched_samples.size() / 2);
+    if (perform_time_stretching) {
+        time_stretcher.AddSamples(&frame[0][0], frame.size());
+        std::vector<s16> stretched_samples = time_stretcher.Process(sink->SamplesInQueue());
+        sink->EnqueueSamples(stretched_samples.data(), stretched_samples.size() / 2);
+    } else {
+        constexpr size_t maximum_sample_latency = 1024; // about 32 miliseconds
+        if (sink->SamplesInQueue() > maximum_sample_latency) {
+            // This can occur if we're running too fast and samples are starting to back up.
+            // Just drop the samples.
+            return;
+        }
+
+        sink->EnqueueSamples(&frame[0][0], frame.size());
+    }
+}
+
+void EnableStretching(bool enable) {
+    if (perform_time_stretching == enable)
+        return;
+
+    if (!enable) {
+        FlushResidualStretcherAudio();
+    }
+    perform_time_stretching = enable;
 }
 
 // Public Interface
@@ -112,12 +144,8 @@ void Init() {
 }
 
 void Shutdown() {
-    time_stretcher.Flush();
-    while (true) {
-        std::vector<s16> residual_audio = time_stretcher.Process(sink->SamplesInQueue());
-        if (residual_audio.empty())
-            break;
-        sink->EnqueueSamples(residual_audio);
+    if (perform_time_stretching) {
+        FlushResidualStretcherAudio();
     }
 }
 
diff --git a/src/audio_core/hle/dsp.h b/src/audio_core/hle/dsp.h
index 9275cd7de..565f20b6f 100644
--- a/src/audio_core/hle/dsp.h
+++ b/src/audio_core/hle/dsp.h
@@ -544,5 +544,13 @@ bool Tick();
  */
 void SetSink(std::unique_ptr<AudioCore::Sink> sink);
 
+/**
+ * Enables/Disables audio-stretching.
+ * Audio stretching is an enhancement that stretches audio to match emulation
+ * speed to prevent stuttering at the cost of some audio latency.
+ * @param enable true to enable, false to disable.
+ */
+void EnableStretching(bool enable);
+
 } // namespace HLE
 } // namespace DSP