aubio_rs/
notes.rs

1use crate::{
2    check_init, ffi,
3    vec::{FVec, FVecMut},
4    Result, Smpl, Status,
5};
6
7/**
8 * Recognized note data
9 */
10#[derive(Debug, Clone, Copy, PartialEq)]
11pub struct Note {
12    pub pitch: Smpl,
13    pub velocity: Smpl,
14}
15
16impl Note {
17    fn parse(values: &[Smpl; 3]) -> Vec<Self> {
18        let mut notes = Vec::new();
19
20        if values[2] != 0.0 {
21            notes.push(Self {
22                pitch: values[2],
23                velocity: 0.0,
24            });
25        }
26
27        if values[0] != 0.0 {
28            notes.push(Self {
29                pitch: values[0],
30                velocity: values[1],
31            });
32        }
33
34        notes
35    }
36}
37
38/**
39 * Notes detection object
40 */
41pub struct Notes {
42    notes: *mut ffi::aubio_notes_t,
43    hop_size: usize,
44}
45
46impl Drop for Notes {
47    fn drop(&mut self) {
48        unsafe { ffi::del_aubio_notes(self.notes) }
49    }
50}
51
52impl Notes {
53    /**
54     * Create notes detection object
55     *
56     * - `buf_size` Buffer size for phase vocoder
57     * - `hop_size` Hop size for phase vocoder
58     * - `samplerate` Sampling rate of the input signal
59     */
60    pub fn new(buf_size: usize, hop_size: usize, sample_rate: u32) -> Result<Self> {
61        let notes = unsafe {
62            ffi::new_aubio_notes(
63                "default\0".as_ptr() as *const _,
64                buf_size as ffi::uint_t,
65                hop_size as ffi::uint_t,
66                sample_rate as ffi::uint_t,
67            )
68        };
69
70        check_init(notes)?;
71
72        Ok(Self { notes, hop_size })
73    }
74
75    /**
76     * Set notes detection silence threshold
77     */
78    pub fn with_silence(mut self, silence: Smpl) -> Self {
79        self.set_silence(silence);
80        self
81    }
82
83    /**
84     * Set notes detection minimum inter-onset interval, in millisecond
85     */
86    pub fn with_minioi_ms(mut self, minioi: Smpl) -> Self {
87        self.set_minioi_ms(minioi);
88        self
89    }
90
91    /**
92     * Set note release drop level, in dB
93     */
94    pub fn with_release_drop(mut self, release_drop: Smpl) -> Self {
95        self.set_release_drop(release_drop);
96        self
97    }
98
99    /**
100     * Get hop size
101     */
102    pub fn get_hop(&self) -> usize {
103        self.hop_size
104    }
105
106    /**
107     * Execute note detection on an input signal frame
108     *
109     * - `input` Input signal of size `hop_size`
110     * - `output` Output notes, fvec of length 3
111     *
112     * The notes output is a vector of length 3 containing:
113     *
114     * 0. the midi note value, or 0 if no note was found
115     * 1. the note velocity
116     * 2. the midi note to turn off
117     */
118    pub fn do_<'i, 'o, I, O>(&mut self, input: I, output: O) -> Status
119    where
120        I: Into<FVec<'i>>,
121        O: Into<FVecMut<'o>>,
122    {
123        let input = input.into();
124        let mut output = output.into();
125
126        input.check_size(self.get_hop())?;
127        output.check_size(3)?;
128
129        unsafe { ffi::aubio_notes_do(self.notes, input.as_ptr(), output.as_mut_ptr()) }
130        Ok(())
131    }
132
133    /**
134     * Execute note detection on an input signal frame
135     */
136    pub fn do_result<'i, I>(&mut self, input: I) -> Result<Vec<Note>>
137    where
138        I: Into<FVec<'i>>,
139    {
140        let mut output = [0.; 3];
141        self.do_(input, output.as_mut())?;
142        Ok(Note::parse(&output))
143    }
144
145    /**
146     * Set notes detection silence threshold
147     */
148    pub fn set_silence(&mut self, silence: Smpl) {
149        unsafe {
150            ffi::aubio_notes_set_silence(self.notes, silence);
151        }
152    }
153
154    /**
155     * Get notes detection silence threshold
156     */
157    pub fn get_silence(&self) -> Smpl {
158        unsafe { ffi::aubio_notes_get_silence(self.notes) }
159    }
160
161    /**
162     * Set notes detection minimum inter-onset interval, in millisecond
163     */
164    pub fn set_minioi_ms(&mut self, minioi: Smpl) {
165        unsafe {
166            ffi::aubio_notes_set_minioi_ms(self.notes, minioi);
167        }
168    }
169
170    /**
171     * Get notes detection minimum inter-onset interval, in millisecond
172     */
173    pub fn get_minioi_ms(&self) -> Smpl {
174        unsafe { ffi::aubio_notes_get_minioi_ms(self.notes) }
175    }
176
177    /**
178     * Set note release drop level, in dB
179     */
180    pub fn set_release_drop(&mut self, release_drop: Smpl) {
181        unsafe {
182            ffi::aubio_notes_set_release_drop(self.notes, release_drop);
183        }
184    }
185
186    /**
187     * Get notes release drop level, in dB
188     */
189    pub fn get_release_drop(&self) -> Smpl {
190        unsafe { ffi::aubio_notes_get_release_drop(self.notes) }
191    }
192}