1
0
Fork 0

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.
This commit is contained in:
Robbert van der Helm 2022-03-06 15:33:16 +01:00
parent e72203f919
commit 2343485c1c
2 changed files with 12 additions and 14 deletions

View file

@ -72,18 +72,18 @@ impl Plugin for Stft {
buffer: &mut Buffer, buffer: &mut Buffer,
_context: &mut impl ProcessContext, _context: &mut impl ProcessContext,
) -> ProcessStatus { ) -> ProcessStatus {
const GAIN_COMPENSATION: f32 = 2.0 / OVERLAP_TIMES as f32;
self.stft.process_overlap_add( self.stft.process_overlap_add(
buffer, buffer,
[], [],
&self.window_function, &self.window_function,
OVERLAP_TIMES, OVERLAP_TIMES,
2.0 / OVERLAP_TIMES as f32, // Gain compensation for the overlap |_channel_idx, _, block| {
|_channel_idx, _, _block| { for sample in block {
// for sample in block { // TODO: Use the FFTW bindings and do some STFT operation here instead of
// // TODO: Use the FFTW bindings and do some STFT operation here instead of // reducing the gain at a 2048 sample latency...
// // reducing the gain at a 2048 sample latency... *sample *= GAIN_COMPENSATION;
// *sample *= 0.5; }
// }
}, },
); );

View file

@ -100,6 +100,9 @@ impl<const NUM_SIDECHAIN_INPUTS: usize> StftHelper<NUM_SIDECHAIN_INPUTS> {
/// [`ProcessContext::set_latency()`][`crate::prelude::ProcessContext::set_latency()`] in your /// [`ProcessContext::set_latency()`][`crate::prelude::ProcessContext::set_latency()`] in your
/// plugin's initialization function. /// 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 /// 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 /// `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, /// time. The arguments to that function are `process_cb(channel_idx, sidechain_buffer_idx,
@ -120,7 +123,6 @@ impl<const NUM_SIDECHAIN_INPUTS: usize> StftHelper<NUM_SIDECHAIN_INPUTS> {
sidechain_buffers: [&Buffer; NUM_SIDECHAIN_INPUTS], sidechain_buffers: [&Buffer; NUM_SIDECHAIN_INPUTS],
window_function: &[f32], window_function: &[f32],
overlap_times: usize, overlap_times: usize,
overlap_gain_compensation: f32,
mut process_cb: F, mut process_cb: F,
) where ) where
F: FnMut(usize, Option<usize>, &mut [f32]), F: FnMut(usize, Option<usize>, &mut [f32]),
@ -227,7 +229,6 @@ impl<const NUM_SIDECHAIN_INPUTS: usize> StftHelper<NUM_SIDECHAIN_INPUTS> {
&self.scratch_buffer, &self.scratch_buffer,
self.current_pos, self.current_pos,
output_ring_buffer, output_ring_buffer,
overlap_gain_compensation,
); );
} }
} }
@ -270,7 +271,6 @@ fn add_scratch_to_ring_buffer(
scratch_buffer: &[f32], scratch_buffer: &[f32],
current_pos: usize, current_pos: usize,
ring_buffer: &mut [f32], ring_buffer: &mut [f32],
gain_compensation: f32,
) { ) {
// TODO: This could also use some SIMD // TODO: This could also use some SIMD
let block_size = scratch_buffer.len(); let block_size = scratch_buffer.len();
@ -279,14 +279,12 @@ fn add_scratch_to_ring_buffer(
.iter() .iter()
.zip(&mut ring_buffer[current_pos..block_size]) .zip(&mut ring_buffer[current_pos..block_size])
{ {
// TODO: Moving this gain compensation to the window is more efficient, but that makes the *ring_sample += *scratch_sample;
// interface less nice to work with
*ring_sample += *scratch_sample * gain_compensation;
} }
for (scratch_sample, ring_sample) in scratch_buffer[num_copy_before_wrap..block_size] for (scratch_sample, ring_sample) in scratch_buffer[num_copy_before_wrap..block_size]
.iter() .iter()
.zip(&mut ring_buffer[0..current_pos]) .zip(&mut ring_buffer[0..current_pos])
{ {
*ring_sample += *scratch_sample * gain_compensation; *ring_sample += *scratch_sample;
} }
} }