summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorozpv <39195175+ozpv@users.noreply.github.com>2026-06-04 05:48:36 +0000
committerGitHub <noreply@github.com>2026-06-04 05:48:36 +0000
commit40ad02bc86872a08b33f60b5d9be0f59d73e36dc (patch)
treec777f8031aa7343831948126cb931f2adbd48ef6
parent57764f725b7877a8d74038f329db8721ec415515 (diff)
use zeroed buffers to start instead
-rw-r--r--src/window_function.rs106
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) {