signalsmith_stretch/
lib.rs1#[allow(non_camel_case_types)]
6mod sys {
7 include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
8}
9
10pub struct Stretch {
12 inner: *mut sys::signalsmith_stretch_t,
13 channel_count: usize,
14}
15
16unsafe impl Send for Stretch {}
17unsafe impl Sync for Stretch {}
18
19impl Stretch {
20 pub fn new(channel_count: u32, block_length: usize, interval: usize) -> Self {
23 let ptr =
24 unsafe { sys::signalsmith_stretch_create(channel_count as _, block_length, interval) };
25
26 Self {
27 inner: ptr,
28 channel_count: channel_count as usize,
29 }
30 }
31
32 pub fn preset_default(channel_count: u32, sample_rate: u32) -> Self {
34 let ptr = unsafe {
35 sys::signalsmith_stretch_create_preset_default(channel_count as i32, sample_rate as f32)
36 };
37
38 Self {
39 inner: ptr,
40 channel_count: channel_count as usize,
41 }
42 }
43
44 pub fn preset_cheaper(channel_count: u32, sample_rate: u32) -> Self {
47 let ptr = unsafe {
48 sys::signalsmith_stretch_create_preset_cheaper(channel_count as i32, sample_rate as f32)
49 };
50
51 Self {
52 inner: ptr,
53 channel_count: channel_count as usize,
54 }
55 }
56
57 pub fn reset(&mut self) {
59 unsafe { sys::signalsmith_stretch_reset(self.inner) }
60 }
61
62 pub fn input_latency(&self) -> usize {
66 unsafe { sys::signalsmith_stretch_input_latency(self.inner) }
67 }
68
69 pub fn output_latency(&self) -> usize {
73 unsafe { sys::signalsmith_stretch_output_latency(self.inner) }
74 }
75
76 pub fn set_transpose_factor(&mut self, multiplier: f32, tonality_limit: Option<f32>) {
78 unsafe {
79 sys::signalsmith_stretch_set_transpose_factor(
80 self.inner,
81 multiplier,
82 tonality_limit.unwrap_or(0.0),
83 )
84 }
85 }
86
87 pub fn set_transpose_factor_semitones(&mut self, semitones: f32, tonality_limit: Option<f32>) {
90 unsafe {
91 sys::signalsmith_stretch_set_transpose_factor_semitones(
92 self.inner,
93 semitones,
94 tonality_limit.unwrap_or(0.0),
95 )
96 }
97 }
98
99 pub fn set_formant_factor(&mut self, multiplier: f32, compensate_pitch: bool) {
101 unsafe {
102 sys::signalsmith_stretch_set_formant_factor(
103 self.inner,
104 multiplier,
105 if compensate_pitch { 1 } else { 0 },
106 )
107 }
108 }
109
110 pub fn set_formant_factor_semitones(&mut self, semitones: f32, compensate_pitch: bool) {
112 unsafe {
113 sys::signalsmith_stretch_set_formant_factor_semitones(
114 self.inner,
115 semitones,
116 if compensate_pitch { 1 } else { 0 },
117 )
118 }
119 }
120
121 pub fn signalsmith_stretch_set_formant_base(&self, frequency: f32) {
124 unsafe { sys::signalsmith_stretch_set_formant_base(self.inner, frequency) }
125 }
126
127 pub fn seek(&mut self, input: impl AsRef<[f32]>, playback_rate: f64) {
131 let input = input.as_ref();
132 let ptr = input.as_ptr();
133
134 debug_assert_eq!(0, input.len() % self.channel_count);
135
136 unsafe {
137 sys::signalsmith_stretch_seek(
138 self.inner,
139 ptr as _,
140 input.len() / self.channel_count,
141 playback_rate,
142 );
143 }
144 }
145
146 pub fn process(&mut self, input: impl AsRef<[f32]>, mut output: impl AsMut<[f32]>) {
152 let input = input.as_ref();
153 let output = output.as_mut();
154
155 debug_assert_eq!(0, input.len() % self.channel_count);
156 debug_assert_eq!(0, output.len() % self.channel_count);
157
158 unsafe {
159 sys::signalsmith_stretch_process(
160 self.inner,
161 input.as_ptr() as _,
162 input.len() / self.channel_count,
163 output.as_mut_ptr(),
164 output.len() / self.channel_count,
165 );
166 }
167 }
168
169 pub fn exact(&mut self, input: impl AsRef<[f32]>, mut output: impl AsMut<[f32]>) -> bool {
171 let input = input.as_ref();
172 let output = output.as_mut();
173
174 debug_assert_eq!(0, input.len() % self.channel_count);
175 debug_assert_eq!(0, output.len() % self.channel_count);
176
177 unsafe {
178 sys::signalsmith_stretch_exact(
179 self.inner,
180 input.as_ptr() as _,
181 input.len() / self.channel_count,
182 output.as_mut_ptr(),
183 output.len() / self.channel_count,
184 )
185 }
186 }
187
188 pub fn flush(&mut self, mut output: impl AsMut<[f32]>) {
191 let output = output.as_mut();
192 debug_assert_eq!(0, output.len() % self.channel_count);
193
194 unsafe {
195 sys::signalsmith_stretch_flush(
196 self.inner,
197 output.as_mut_ptr(),
198 output.len() / self.channel_count,
199 );
200 }
201 }
202}
203
204impl Drop for Stretch {
205 fn drop(&mut self) {
206 unsafe { sys::signalsmith_stretch_destroy(self.inner) }
207 }
208}