diff options
| author | 2016-08-31 16:56:30 +0100 | |
|---|---|---|
| committer | 2016-08-31 16:56:30 +0100 | |
| commit | 904a31969469a5ecff7eacfddc8541ea5996dcdf (patch) | |
| tree | 369e91b89e1f4b2aef805b9f85c734d377ce631e /src | |
| parent | sink: Change EnqueueSamples to take a pointer to a buffer instead of a std::v... (diff) | |
| download | yuzu-904a31969469a5ecff7eacfddc8541ea5996dcdf.tar.gz yuzu-904a31969469a5ecff7eacfddc8541ea5996dcdf.tar.xz yuzu-904a31969469a5ecff7eacfddc8541ea5996dcdf.zip | |
audio_core: Add EnableStretching to interface so that one can toggle stretching on and off
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/audio_core.cpp | 4 | ||||
| -rw-r--r-- | src/audio_core/audio_core.h | 3 | ||||
| -rw-r--r-- | src/audio_core/hle/dsp.cpp | 46 | ||||
| -rw-r--r-- | src/audio_core/hle/dsp.h | 8 |
4 files changed, 52 insertions, 9 deletions
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) { | |||
| 71 | DSP::HLE::SetSink(iter->factory()); | 71 | DSP::HLE::SetSink(iter->factory()); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | void EnableStretching(bool enable) { | ||
| 75 | DSP::HLE::EnableStretching(enable); | ||
| 76 | } | ||
| 77 | |||
| 74 | void Shutdown() { | 78 | void Shutdown() { |
| 75 | CoreTiming::UnscheduleEvent(tick_event, 0); | 79 | CoreTiming::UnscheduleEvent(tick_event, 0); |
| 76 | DSP::HLE::Shutdown(); | 80 | 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); | |||
| 23 | /// Select the sink to use based on sink id. | 23 | /// Select the sink to use based on sink id. |
| 24 | void SelectSink(std::string sink_id); | 24 | void SelectSink(std::string sink_id); |
| 25 | 25 | ||
| 26 | /// Enable/Disable stretching. | ||
| 27 | void EnableStretching(bool enable); | ||
| 28 | |||
| 26 | /// Shutdown Audio Core | 29 | /// Shutdown Audio Core |
| 27 | void Shutdown(); | 30 | void Shutdown(); |
| 28 | 31 | ||
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 | ||
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(); | |||
| 544 | */ | 544 | */ |
| 545 | void SetSink(std::unique_ptr<AudioCore::Sink> sink); | 545 | void SetSink(std::unique_ptr<AudioCore::Sink> sink); |
| 546 | 546 | ||
| 547 | /** | ||
| 548 | * Enables/Disables audio-stretching. | ||
| 549 | * Audio stretching is an enhancement that stretches audio to match emulation | ||
| 550 | * speed to prevent stuttering at the cost of some audio latency. | ||
| 551 | * @param enable true to enable, false to disable. | ||
| 552 | */ | ||
| 553 | void EnableStretching(bool enable); | ||
| 554 | |||
| 547 | } // namespace HLE | 555 | } // namespace HLE |
| 548 | } // namespace DSP | 556 | } // namespace DSP |