From 2343485c1ce2ebb8f6f5c1ecc3e9bdfda603076b Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 6 Mar 2022 15:33:16 +0100 Subject: [PATCH] Don't do gain compensation in STFT helper You'll likely want to add some scaling yourself anyways, so this would just be a wasted operation since the scaling also depends on your window function. --- plugins/examples/stft/src/lib.rs | 14 +++++++------- src/util/stft.rs | 12 +++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/plugins/examples/stft/src/lib.rs b/plugins/examples/stft/src/lib.rs index 1eb79027..8aa0c74b 100644 --- a/plugins/examples/stft/src/lib.rs +++ b/plugins/examples/stft/src/lib.rs @@ -72,18 +72,18 @@ impl Plugin for Stft { buffer: &mut Buffer, _context: &mut impl ProcessContext, ) -> ProcessStatus { + const GAIN_COMPENSATION: f32 = 2.0 / OVERLAP_TIMES as f32; self.stft.process_overlap_add( buffer, [], &self.window_function, OVERLAP_TIMES, - 2.0 / OVERLAP_TIMES as f32, // Gain compensation for the overlap - |_channel_idx, _, _block| { - // for sample in block { - // // TODO: Use the FFTW bindings and do some STFT operation here instead of - // // reducing the gain at a 2048 sample latency... - // *sample *= 0.5; - // } + |_channel_idx, _, block| { + for sample in block { + // TODO: Use the FFTW bindings and do some STFT operation here instead of + // reducing the gain at a 2048 sample latency... + *sample *= GAIN_COMPENSATION; + } }, ); diff --git a/src/util/stft.rs b/src/util/stft.rs index ff209f1a..69dd25ea 100644 --- a/src/util/stft.rs +++ b/src/util/stft.rs @@ -100,6 +100,9 @@ impl StftHelper { /// [`ProcessContext::set_latency()`][`crate::prelude::ProcessContext::set_latency()`] in your /// plugin's initialization function. /// + /// This function does not apply any gain compensation for the windowing. You will need to do + /// that yoruself depending on your window function and the amount of overlap. + /// /// For efficiency's sake this function will reuse the same vector for all calls to /// `process_cb`. This means you can only access a single channel's worth of windowed data at a /// time. The arguments to that function are `process_cb(channel_idx, sidechain_buffer_idx, @@ -120,7 +123,6 @@ impl StftHelper { sidechain_buffers: [&Buffer; NUM_SIDECHAIN_INPUTS], window_function: &[f32], overlap_times: usize, - overlap_gain_compensation: f32, mut process_cb: F, ) where F: FnMut(usize, Option, &mut [f32]), @@ -227,7 +229,6 @@ impl StftHelper { &self.scratch_buffer, self.current_pos, output_ring_buffer, - overlap_gain_compensation, ); } } @@ -270,7 +271,6 @@ fn add_scratch_to_ring_buffer( scratch_buffer: &[f32], current_pos: usize, ring_buffer: &mut [f32], - gain_compensation: f32, ) { // TODO: This could also use some SIMD let block_size = scratch_buffer.len(); @@ -279,14 +279,12 @@ fn add_scratch_to_ring_buffer( .iter() .zip(&mut ring_buffer[current_pos..block_size]) { - // TODO: Moving this gain compensation to the window is more efficient, but that makes the - // interface less nice to work with - *ring_sample += *scratch_sample * gain_compensation; + *ring_sample += *scratch_sample; } for (scratch_sample, ring_sample) in scratch_buffer[num_copy_before_wrap..block_size] .iter() .zip(&mut ring_buffer[0..current_pos]) { - *ring_sample += *scratch_sample * gain_compensation; + *ring_sample += *scratch_sample; } }