1use {FloatSample, Sample};
5use core;
6use core::marker::PhantomData;
7use frame::Frame;
8use signal::{self, Signal};
9
10pub trait Type {
12 fn at_phase<S: Sample>(phase: S) -> S;
14}
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub struct Hanning;
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
25pub struct Rectangle;
26
27#[derive(Clone)]
30pub struct Window<F, W>
31where
32 F: Frame,
33 W: Type,
34{
35 pub phase: signal::Phase<signal::ConstHz>,
37 marker: PhantomData<(F, W)>,
38}
39
40#[derive(Clone)]
42pub struct Windower<'a, F, W>
43where
44 F: 'a + Frame,
45 W: Type,
46{
47 pub bin: usize,
49 pub hop: usize,
51 pub frames: &'a [F],
53 wttype: PhantomData<W>,
54}
55
56#[derive(Clone)]
60pub struct Windowed<S, W>
61where
62 S: Signal,
63 W: Type,
64{
65 signal: S,
66 window: Window<<S::Frame as Frame>::Float, W>,
67}
68
69
70impl Type for Hanning {
71 fn at_phase<S: Sample>(phase: S) -> S {
72 const PI_2: f64 = core::f64::consts::PI * 2.0;
73 let v = phase.to_float_sample().to_sample() * PI_2;
74 (0.5 * (1.0 - super::ops::f64::cos(v)))
75 .to_sample::<S::Float>()
76 .to_sample::<S>()
77 }
78}
79
80impl Type for Rectangle {
81 fn at_phase<S: Sample>(_phase: S) -> S {
82 <S::Float as FloatSample>::identity().to_sample::<S>()
83 }
84}
85
86
87impl<F, W> Window<F, W>
88where
89 F: Frame,
90 W: Type,
91{
92 pub fn new(len: usize) -> Self {
94 let step = signal::rate(len as f64 - 1.0).const_hz(1.0);
95 Window {
96 phase: signal::phase(step),
97 marker: PhantomData,
98 }
99 }
100}
101
102
103impl<'a, F, W> Windower<'a, F, W>
104where
105 F: 'a + Frame,
106 W: Type,
107{
108 pub fn new(frames: &'a [F], bin: usize, hop: usize) -> Self {
110 Windower {
111 bin: bin,
112 hop: hop,
113 frames: frames,
114 wttype: PhantomData,
115 }
116 }
117}
118
119impl<'a, F> Windower<'a, F, Rectangle>
120where
121 F: 'a + Frame,
122{
123 pub fn rectangle(frames: &'a [F], bin: usize, hop: usize) -> Self {
125 Windower::new(frames, bin, hop)
126 }
127}
128
129impl<'a, F> Windower<'a, F, Hanning>
130where
131 F: 'a + Frame,
132{
133 pub fn hanning(frames: &'a [F], bin: usize, hop: usize) -> Self {
135 Windower::new(frames, bin, hop)
136 }
137}
138
139
140impl<F, W> Iterator for Window<F, W>
141where
142 F: Frame,
143 W: Type,
144{
145 type Item = F;
146
147 fn next(&mut self) -> Option<Self::Item> {
148 let v = W::at_phase(self.phase.next_phase());
149 let v_f: <F::Sample as Sample>::Float = v.to_sample();
150 Some(F::from_fn(|_| v_f.to_sample::<F::Sample>()))
151 }
152}
153
154impl<'a, F, W> Iterator for Windower<'a, F, W>
155where
156 F: 'a + Frame,
157 W: Type,
158{
159 type Item = Windowed<signal::FromIterator<core::iter::Cloned<core::slice::Iter<'a, F>>>, W>;
160
161 fn next(&mut self) -> Option<Self::Item> {
162 let num_frames = self.frames.len();
163 if self.bin <= num_frames {
164 let frames = &self.frames[..self.bin];
165 let window = Window::new(self.bin);
166 self.frames = if self.hop < num_frames {
167 &self.frames[self.hop..]
168 } else {
169 &[]
170 };
171 Some(Windowed {
172 signal: signal::from_iter(frames.iter().cloned()),
173 window: window,
174 })
175 } else {
176 None
177 }
178 }
179
180 fn size_hint(&self) -> (usize, Option<usize>) {
181 let num_frames = self.frames.len();
182 if self.bin < num_frames {
184 if self.hop == 0 {
186 return (core::usize::MAX, None);
187 }
188 let remaining_hop_frames = self.frames.len() - self.bin;
190 let remaining_iterations = remaining_hop_frames / self.hop;
191 (remaining_iterations, Some(remaining_iterations))
192 } else {
193 (0, Some(0))
194 }
195 }
196}
197
198impl<S, W> Iterator for Windowed<S, W>
199where
200 S: Signal,
201 W: Type,
202{
203 type Item = S::Frame;
204 fn next(&mut self) -> Option<Self::Item> {
205 self.window.next().map(|w_f| {
206 let s_f = self.signal.next();
207 s_f.mul_amp(w_f)
208 })
209 }
210}
211
212pub fn hanning<F>(num_frames: usize) -> Window<F, Hanning>
214where
215 F: Frame,
216{
217 Window::new(num_frames)
218}
219
220pub fn rectangle<F>(num_frames: usize) -> Window<F, Rectangle>
222where
223 F: Frame,
224{
225 Window::new(num_frames)
226}