1use crate::{
2 check_init, ffi,
3 vec::{CVec, CVecMut, FVec, FVecMut},
4 AsNativeStr, Error, Result, Status, WindowType,
5};
6
7pub struct PVoc {
11 pvoc: *mut ffi::aubio_pvoc_t,
12}
13
14impl Drop for PVoc {
15 fn drop(&mut self) {
16 unsafe {
17 ffi::del_aubio_pvoc(self.pvoc);
18 }
19 }
20}
21
22impl PVoc {
23 pub fn new(win_size: usize, hop_size: usize) -> Result<Self> {
30 let pvoc = unsafe { ffi::new_aubio_pvoc(win_size as ffi::uint_t, hop_size as ffi::uint_t) };
31
32 check_init(pvoc)?;
33
34 Ok(Self { pvoc })
35 }
36
37 pub fn with_window(mut self, window_type: WindowType) -> Result<Self> {
41 self.set_window(window_type).map(|_| self)
42 }
43
44 pub fn get_hop(&self) -> usize {
48 unsafe { ffi::aubio_pvoc_get_hop(self.pvoc) as usize }
49 }
50
51 pub fn get_win(&self) -> usize {
55 unsafe { ffi::aubio_pvoc_get_win(self.pvoc) as usize }
56 }
57
58 pub fn do_<'i, 'o, I, O>(&mut self, input: I, fftgrain: O) -> Status
71 where
72 I: Into<FVec<'i>>,
73 O: Into<CVecMut<'o>>,
74 {
75 let input = input.into();
76 let mut fftgrain = fftgrain.into();
77
78 input.check_size(self.get_hop())?;
79 fftgrain.check_size(self.get_win())?;
80
81 unsafe {
82 ffi::aubio_pvoc_do(self.pvoc, input.as_ptr(), fftgrain.as_mut_ptr());
83 }
84 Ok(())
85 }
86
87 pub fn rdo<'i, 'o, I, O>(&mut self, fftgrain: I, output: O) -> Status
97 where
98 I: Into<CVec<'i>>,
99 O: Into<FVecMut<'o>>,
100 {
101 let fftgrain = fftgrain.into();
102 let mut output = output.into();
103
104 fftgrain.check_size(self.get_win())?;
105 output.check_size(self.get_hop())?;
106
107 unsafe {
109 ffi::aubio_pvoc_rdo(self.pvoc, fftgrain.as_ptr() as *mut _, output.as_mut_ptr());
110 }
111 Ok(())
112 }
113
114 pub fn set_window(&mut self, window_type: WindowType) -> Status {
118 if 0 == unsafe { ffi::aubio_pvoc_set_window(self.pvoc, window_type.as_native_cstr()) } {
119 Ok(())
120 } else {
121 Err(Error::InvalidArg)
122 }
123 }
124}
125
126#[cfg(test)]
127mod test {
128 use crate::*;
129
130 #[test]
131 fn test() {
132 const WIN_S: usize = 32; const HOP_S: usize = WIN_S / 4; let in_ = [1.; HOP_S]; let mut fftgrain = carr!(WIN_S); let mut out = farr!(HOP_S); let mut pv = PVoc::new(WIN_S, HOP_S).unwrap();
139
140 assert!(PVoc::new(WIN_S, 0).is_err());
141 assert_eq!(pv.get_win(), WIN_S);
142 assert_eq!(pv.get_hop(), HOP_S);
143
144 pv.set_window(WindowType::Hanningz).unwrap();
145
146 for _i in 0..6 {
148 pv.do_(in_.as_ref(), fftgrain.as_mut()).unwrap();
152 println!("fftgrain: {:?}", fftgrain.as_ref());
155
156 pv.rdo(fftgrain.as_ref(), out.as_mut()).unwrap();
158 println!("out: {:?}", out);
161 }
162 }
163}