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:
parent
e72203f919
commit
2343485c1c
|
@ -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;
|
}
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue