diff options
Diffstat (limited to 'src/audio_core/hle/dsp.cpp')
| -rw-r--r-- | src/audio_core/hle/dsp.cpp | 46 |
1 files changed, 37 insertions, 9 deletions
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() { | |||
| 85 | 85 | ||
| 86 | // Audio output | 86 | // Audio output |
| 87 | 87 | ||
| 88 | static bool perform_time_stretching = true; | ||
| 88 | static std::unique_ptr<AudioCore::Sink> sink; | 89 | static std::unique_ptr<AudioCore::Sink> sink; |
| 89 | static AudioCore::TimeStretcher time_stretcher; | 90 | static AudioCore::TimeStretcher time_stretcher; |
| 90 | 91 | ||
| 92 | static void FlushResidualStretcherAudio() { | ||
| 93 | time_stretcher.Flush(); | ||
| 94 | while (true) { | ||
| 95 | std::vector<s16> residual_audio = time_stretcher.Process(sink->SamplesInQueue()); | ||
| 96 | if (residual_audio.empty()) | ||
| 97 | break; | ||
| 98 | sink->EnqueueSamples(residual_audio.data(), residual_audio.size() / 2); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 91 | static void OutputCurrentFrame(const StereoFrame16& frame) { | 102 | static void OutputCurrentFrame(const StereoFrame16& frame) { |
| 92 | time_stretcher.AddSamples(&frame[0][0], frame.size()); | 103 | if (perform_time_stretching) { |
| 93 | std::vector<s16> stretched_samples = time_stretcher.Process(sink->SamplesInQueue()); | 104 | time_stretcher.AddSamples(&frame[0][0], frame.size()); |
| 94 | sink->EnqueueSamples(stretched_samples.data(), stretched_samples.size() / 2); | 105 | std::vector<s16> stretched_samples = time_stretcher.Process(sink->SamplesInQueue()); |
| 106 | sink->EnqueueSamples(stretched_samples.data(), stretched_samples.size() / 2); | ||
| 107 | } else { | ||
| 108 | constexpr size_t maximum_sample_latency = 1024; // about 32 miliseconds | ||
| 109 | if (sink->SamplesInQueue() > maximum_sample_latency) { | ||
| 110 | // This can occur if we're running too fast and samples are starting to back up. | ||
| 111 | // Just drop the samples. | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | |||
| 115 | sink->EnqueueSamples(&frame[0][0], frame.size()); | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | void EnableStretching(bool enable) { | ||
| 120 | if (perform_time_stretching == enable) | ||
| 121 | return; | ||
| 122 | |||
| 123 | if (!enable) { | ||
| 124 | FlushResidualStretcherAudio(); | ||
| 125 | } | ||
| 126 | perform_time_stretching = enable; | ||
| 95 | } | 127 | } |
| 96 | 128 | ||
| 97 | // Public Interface | 129 | // Public Interface |
| @@ -112,12 +144,8 @@ void Init() { | |||
| 112 | } | 144 | } |
| 113 | 145 | ||
| 114 | void Shutdown() { | 146 | void Shutdown() { |
| 115 | time_stretcher.Flush(); | 147 | if (perform_time_stretching) { |
| 116 | while (true) { | 148 | FlushResidualStretcherAudio(); |
| 117 | std::vector<s16> residual_audio = time_stretcher.Process(sink->SamplesInQueue()); | ||
| 118 | if (residual_audio.empty()) | ||
| 119 | break; | ||
| 120 | sink->EnqueueSamples(residual_audio); | ||
| 121 | } | 149 | } |
| 122 | } | 150 | } |
| 123 | 151 | ||