diff options
| author | ozpv <39195175+ozpv@users.noreply.github.com> | 2026-06-04 05:48:36 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-06-04 05:48:36 +0000 |
| commit | 40ad02bc86872a08b33f60b5d9be0f59d73e36dc (patch) | |
| tree | c777f8031aa7343831948126cb931f2adbd48ef6 | |
| parent | 57764f725b7877a8d74038f329db8721ec415515 (diff) | |
use zeroed buffers to start instead
| -rw-r--r-- | src/window_function.rs | 106 |
1 files changed, 25 insertions, 81 deletions
diff --git a/src/window_function.rs b/src/window_function.rs index 0234d81..3d59953 100644 --- a/src/window_function.rs +++ b/src/window_function.rs @@ -18,6 +18,10 @@ pub struct RectangularWindow { } impl RectangularWindow { + // I'm thinking of turning this into a polyphonic synth for low retain order + // to eliminate clicking and keep a "glitchy" sound + // a max of < 64 voices for normal mode + // and window_size - 64 <= n < window_size for complement mode pub fn new(window_size: &WindowSize) -> Self { Self { window_size: window_size.inner(), @@ -40,6 +44,7 @@ impl WindowFunction for RectangularWindow { } /// Hann function +/// Implemented using sqrt Hann pub struct HannWindow { window_size: usize, function: Vec<f32>, @@ -53,7 +58,6 @@ impl HannWindow { let half_window_size = window_size / 2; let window_size_f32 = window_size as f32; - // bypass the need for a normalize buffer by using sqrt let function = (0..window_size) .map(|i| { let i = i as f32; @@ -62,10 +66,13 @@ impl HannWindow { }) .collect::<Vec<f32>>(); + let mut previous = Vec::with_capacity(window_size); + previous.resize(half_window_size, 0.0); + Self { window_size, function, - previous: Vec::with_capacity(half_window_size), + previous, overlap_add: vec![0.0; window_size], } } @@ -75,29 +82,14 @@ impl WindowFunction for HannWindow { fn apply(&mut self, data: &mut VecDeque<f32>) { let half_window_size = self.window_size / 2; - // the full window size is needed to window over the samples the first time - if self.previous.is_empty() { - // store the latter half for when only half the size is needed - for sample in data.iter().skip(half_window_size).copied() { - self.previous.push(sample); - } - - // apply the function - for (i, sample) in data.iter_mut().enumerate() { - *sample *= self.function[i]; - } - - return; - } - - // In a real time "sliding window" it's necessary to add in the previous samples + // "sliding window" for sample in self.previous.iter().rev().copied() { data.push_front(sample); } self.previous.clear(); - // keep this iteration's samples for the next window + // keep these samples for the next window for sample in data.iter().skip(half_window_size).copied() { self.previous.push(sample); } @@ -132,11 +124,7 @@ impl WindowFunction for HannWindow { } fn needed(&self) -> usize { - if self.previous.is_empty() { - self.window_size - } else { - self.window_size / 2 - } + self.window_size / 2 } fn resize(&mut self, window_size: &WindowSize) { @@ -161,8 +149,6 @@ impl HammingWindow { let overlap_add = vec![0.0; window_size]; - let previous = Vec::with_capacity(half_window_size); - let function = (0..window_size) .map(|i| { let i = i as f32; @@ -171,6 +157,7 @@ impl HammingWindow { }) .collect::<Vec<f32>>(); + // not exact but good enough let normalize = (0..half_window_size) .map(|i| { (function[i] * function[i]) @@ -178,6 +165,9 @@ impl HammingWindow { }) .collect::<Vec<f32>>(); + let mut previous = Vec::with_capacity(window_size); + previous.resize(half_window_size, 0.0); + Self { window_size, function, @@ -192,18 +182,6 @@ impl WindowFunction for HammingWindow { fn apply(&mut self, data: &mut VecDeque<f32>) { let half_window_size = self.window_size / 2; - if self.previous.is_empty() { - for sample in data.iter().skip(half_window_size).copied() { - self.previous.push(sample); - } - - for (i, sample) in data.iter_mut().enumerate() { - *sample *= self.function[i]; - } - - return; - } - for sample in self.previous.iter().rev().copied() { data.push_front(sample); } @@ -242,11 +220,7 @@ impl WindowFunction for HammingWindow { } fn needed(&self) -> usize { - if self.previous.is_empty() { - self.window_size - } else { - self.window_size / 2 - } + self.window_size / 2 } fn resize(&mut self, window_size: &WindowSize) { @@ -277,8 +251,6 @@ impl BlackmanHarrisWindow { let overlap_add = vec![0.0; window_size]; - let previous = Vec::with_capacity(three_quarters_window_size); - let function = (0..window_size) .map(|i| { let i = i as f32; @@ -301,6 +273,9 @@ impl BlackmanHarrisWindow { }) .collect::<Vec<f32>>(); + let mut previous = Vec::with_capacity(window_size); + previous.resize(three_quarters_window_size, 0.0); + Self { window_size, function, @@ -315,18 +290,6 @@ impl WindowFunction for BlackmanHarrisWindow { fn apply(&mut self, data: &mut VecDeque<f32>) { let quarter_window_size = self.window_size / 4; - if self.previous.is_empty() { - for sample in data.iter().skip(quarter_window_size).copied() { - self.previous.push(sample); - } - - for (i, sample) in data.iter_mut().enumerate() { - *sample *= self.function[i]; - } - - return; - } - for sample in self.previous.iter().rev().copied() { data.push_front(sample); } @@ -366,11 +329,7 @@ impl WindowFunction for BlackmanHarrisWindow { } fn needed(&self) -> usize { - if self.previous.is_empty() { - self.window_size - } else { - self.window_size / 4 - } + self.window_size / 4 } fn resize(&mut self, window_size: &WindowSize) { @@ -400,8 +359,6 @@ impl Sine4Window { let overlap_add = vec![0.0; window_size]; - let previous = Vec::with_capacity(three_quarters_window_size); - let function = (0..window_size) .map(|i| { let i = i as f32; @@ -423,6 +380,9 @@ impl Sine4Window { }) .collect::<Vec<f32>>(); + let mut previous = Vec::with_capacity(window_size); + previous.resize(three_quarters_window_size, 0.0); + Self { window_size, function, @@ -437,18 +397,6 @@ impl WindowFunction for Sine4Window { fn apply(&mut self, data: &mut VecDeque<f32>) { let quarter_window_size = self.window_size / 4; - if self.previous.is_empty() { - for sample in data.iter().skip(quarter_window_size).copied() { - self.previous.push(sample); - } - - for (i, sample) in data.iter_mut().enumerate() { - *sample *= self.function[i]; - } - - return; - } - for sample in self.previous.iter().rev().copied() { data.push_front(sample); } @@ -488,11 +436,7 @@ impl WindowFunction for Sine4Window { } fn needed(&self) -> usize { - if self.previous.is_empty() { - self.window_size - } else { - self.window_size / 4 - } + self.window_size / 4 } fn resize(&mut self, window_size: &WindowSize) { |
