From 0bb4cbc498278bead688bb564654ba8837f780ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ju=CC=88rgen=20Hock?= Date: Fri, 17 Nov 2023 17:17:20 +0100 Subject: [PATCH] Reuse buffer vectors --- cpp/StftPitchShift/STFT.h | 68 +++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/cpp/StftPitchShift/STFT.h b/cpp/StftPitchShift/STFT.h index 8522fce..becc17d 100755 --- a/cpp/StftPitchShift/STFT.h +++ b/cpp/StftPitchShift/STFT.h @@ -46,34 +46,32 @@ namespace stftpitchshift if (analysis_window_size == synthesis_window_size) { - windows.analysis = symmetric_window(analysis_window_size); - windows.synthesis = windows.analysis; + window.analysis = symmetric_window(analysis_window_size); + window.synthesis = window.analysis; } else { - windows.analysis = asymmetric_analysis_window(analysis_window_size, synthesis_window_size); - windows.synthesis = asymmetric_synthesis_window(analysis_window_size, synthesis_window_size); + window.analysis = asymmetric_analysis_window(analysis_window_size, synthesis_window_size); + window.synthesis = asymmetric_synthesis_window(analysis_window_size, synthesis_window_size); } const T unitygain = hopsize / std::inner_product( - windows.analysis.begin(), windows.analysis.end(), windows.synthesis.begin(), T(0)); + window.analysis.begin(), window.analysis.end(), window.synthesis.begin(), T(0)); - std::transform(windows.synthesis.begin(), windows.synthesis.end(), windows.synthesis.begin(), + std::transform(window.synthesis.begin(), window.synthesis.end(), window.synthesis.begin(), [unitygain](T value) { return value * unitygain; }); + + buffer.size = analysis_window_size; + buffer.time.resize(buffer.size); + buffer.freq.resize(buffer.size / 2 + 1); } - void operator()(const std::span input, const std::span output, const std::function> dft)> callback) const + void operator()(const std::span input, const std::span output, const std::function> dft)> callback) { const size_t samples = (std::min)(input.size(), output.size()); - const size_t analysis_window_size = std::get<0>(framesize); - const size_t synthesis_window_size = std::get<1>(framesize); - std::fill(output.begin(), output.end(), T(0)); // clear output #30 - std::vector frame(analysis_window_size); - std::vector> dft(analysis_window_size / 2 + 1); - if (chronometry) { struct @@ -86,20 +84,23 @@ namespace stftpitchshift timers; timers.loop.tic(); - for (size_t hop = 0; (hop + synthesis_window_size) < samples; hop += hopsize) + for (size_t hop = 0; (hop + buffer.size) < samples; hop += hopsize) { + const std::span src = input.subspan(hop, buffer.size); + const std::span dst = output.subspan(hop, buffer.size); + timers.analysis.tic(); - reject(input.subspan(hop, synthesis_window_size), frame, windows.analysis); - transform(frame, dft); + reject(src, buffer.time, window.analysis); + transform(buffer.time, buffer.freq); timers.analysis.toc(); timers.callback.tic(); - callback(dft); + callback(buffer.freq); timers.callback.toc(); timers.synthesis.tic(); - transform(dft, frame); - inject(output.subspan(hop, synthesis_window_size), frame, windows.synthesis); + transform(buffer.freq, buffer.time); + inject(dst, buffer.time, window.synthesis); timers.synthesis.toc(); } timers.loop.toc(); @@ -111,15 +112,18 @@ namespace stftpitchshift } else { - for (size_t hop = 0; (hop + synthesis_window_size) < samples; hop += hopsize) + for (size_t hop = 0; (hop + buffer.size) < samples; hop += hopsize) { - reject(input.subspan(hop, synthesis_window_size), frame, windows.analysis); - transform(frame, dft); + const std::span src = input.subspan(hop, buffer.size); + const std::span dst = output.subspan(hop, buffer.size); + + reject(src, buffer.time, window.analysis); + transform(buffer.time, buffer.freq); - callback(dft); + callback(buffer.freq); - transform(dft, frame); - inject(output.subspan(hop, synthesis_window_size), frame, windows.synthesis); + transform(buffer.freq, buffer.time); + inject(dst, buffer.time, window.synthesis); } } } @@ -136,7 +140,15 @@ namespace stftpitchshift std::vector analysis; std::vector synthesis; } - windows; + window; + + struct + { + size_t size; + std::vector time; + std::vector> freq; + } + buffer; inline void transform(const std::span frame, const std::span> dft) const { @@ -160,7 +172,7 @@ namespace stftpitchshift fft->ifft(dft, frame); } - inline void reject(const std::span input, const std::span frame, const std::vector& window) const + inline void reject(const std::span input, const std::span frame, const std::span window) const { for (size_t i = 0; i < window.size(); ++i) { @@ -168,7 +180,7 @@ namespace stftpitchshift } } - inline void inject(const std::span output, const std::span frame, const std::vector& window) const + inline void inject(const std::span output, const std::span frame, const std::span window) const { for (size_t i = 0; i < window.size(); ++i) {