webrtc_audio_processing_sys/
lib.rs1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
6
7impl Into<Option<bool>> for OptionalBool {
8 fn into(self) -> Option<bool> {
9 if self.has_value {
10 Some(self.value)
11 } else {
12 None
13 }
14 }
15}
16
17impl From<Option<bool>> for OptionalBool {
18 fn from(other: Option<bool>) -> OptionalBool {
19 if let Some(value) = other {
20 OptionalBool { has_value: true, value }
21 } else {
22 OptionalBool { has_value: false, value: false }
23 }
24 }
25}
26
27impl Into<Option<i32>> for OptionalInt {
28 fn into(self) -> Option<i32> {
29 if self.has_value {
30 Some(self.value)
31 } else {
32 None
33 }
34 }
35}
36
37impl From<Option<i32>> for OptionalInt {
38 fn from(other: Option<i32>) -> OptionalInt {
39 if let Some(value) = other {
40 OptionalInt { has_value: true, value }
41 } else {
42 OptionalInt { has_value: false, value: 0 }
43 }
44 }
45}
46
47impl Into<Option<f64>> for OptionalDouble {
48 fn into(self) -> Option<f64> {
49 if self.has_value {
50 Some(self.value)
51 } else {
52 None
53 }
54 }
55}
56
57impl From<Option<f64>> for OptionalDouble {
58 fn from(other: Option<f64>) -> OptionalDouble {
59 if let Some(value) = other {
60 OptionalDouble { has_value: true, value }
61 } else {
62 OptionalDouble { has_value: false, value: 0.0 }
63 }
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 fn init_config_with_all_enabled() -> InitializationConfig {
72 InitializationConfig {
73 num_capture_channels: 1,
74 num_render_channels: 1,
75 enable_experimental_agc: true,
76 enable_intelligibility_enhancer: true,
77 }
78 }
79
80 fn config_with_all_enabled() -> Config {
81 Config {
82 echo_cancellation: EchoCancellation {
83 enable: true,
84 suppression_level: EchoCancellation_SuppressionLevel::HIGH,
85 },
86 gain_control: GainControl {
87 enable: true,
88 target_level_dbfs: 3,
89 compression_gain_db: 3,
90 enable_limiter: true,
91 },
92 noise_suppression: NoiseSuppression {
93 enable: true,
94 suppression_level: NoiseSuppression_SuppressionLevel::HIGH,
95 },
96 voice_detection: VoiceDetection {
97 enable: true,
98 detection_likelihood: VoiceDetection_DetectionLikelihood::HIGH,
99 },
100 enable_extended_filter: true,
101 enable_delay_agnostic: true,
102 enable_transient_suppressor: true,
103 enable_high_pass_filter: true,
104 }
105 }
106
107 #[test]
108 fn test_create_failure() {
109 unsafe {
110 let config = InitializationConfig::default();
111 let mut error = 0;
112 let ap = audio_processing_create(&config, &mut error);
113 assert!(ap.is_null());
114 assert!(!is_success(error));
115 }
116 }
117
118 #[test]
119 fn test_create_delete() {
120 unsafe {
121 let config = InitializationConfig {
122 num_capture_channels: 1,
123 num_render_channels: 1,
124 ..InitializationConfig::default()
125 };
126 let mut error = 0;
127 let ap = audio_processing_create(&config, &mut error);
128 assert!(!ap.is_null());
129 assert!(is_success(error));
130 audio_processing_delete(ap);
131 }
132 }
133
134 #[test]
135 fn test_config() {
136 unsafe {
137 let mut error = 0;
138 let ap = audio_processing_create(&init_config_with_all_enabled(), &mut error);
139 assert!(!ap.is_null());
140 assert!(is_success(error));
141
142 let config = Config::default();
143 set_config(ap, &config);
144
145 let config = config_with_all_enabled();
146 set_config(ap, &config);
147
148 audio_processing_delete(ap);
149 }
150 }
151
152 #[test]
153 fn test_process() {
154 unsafe {
155 let mut error = 0;
156 let ap = audio_processing_create(&init_config_with_all_enabled(), &mut error);
157 assert!(!ap.is_null());
158 assert!(is_success(error));
159
160 let config = config_with_all_enabled();
161 set_config(ap, &config);
162
163 let mut frame = vec![vec![0f32; NUM_SAMPLES_PER_FRAME as usize]; 1];
164 let mut frame_ptr = frame.iter_mut().map(|v| v.as_mut_ptr()).collect::<Vec<*mut f32>>();
165 assert!(is_success(process_render_frame(ap, frame_ptr.as_mut_ptr())));
166 assert!(is_success(process_capture_frame(ap, frame_ptr.as_mut_ptr())));
167
168 audio_processing_delete(ap);
169 }
170 }
171
172 #[test]
173 fn test_empty_stats() {
174 unsafe {
175 let config = InitializationConfig {
176 num_capture_channels: 1,
177 num_render_channels: 1,
178 ..InitializationConfig::default()
179 };
180 let mut error = 0;
181 let ap = audio_processing_create(&config, &mut error);
182 assert!(!ap.is_null());
183 assert!(is_success(error));
184
185 let stats = get_stats(ap);
186 println!("Stats:\n{:#?}", stats);
187 assert!(!stats.has_voice.has_value);
188 assert!(!stats.has_echo.has_value);
189 assert!(!stats.rms_dbfs.has_value);
190 assert!(!stats.speech_probability.has_value);
191 assert!(!stats.residual_echo_return_loss.has_value);
192 assert!(!stats.echo_return_loss.has_value);
193 assert!(!stats.echo_return_loss_enhancement.has_value);
194 assert!(!stats.a_nlp.has_value);
195 assert!(!stats.delay_median_ms.has_value);
196 assert!(!stats.delay_standard_deviation_ms.has_value);
197 assert!(!stats.delay_fraction_poor_delays.has_value);
198
199 audio_processing_delete(ap);
200 }
201 }
202
203 #[test]
204 fn test_some_stats() {
205 unsafe {
206 let mut error = 0;
207 let ap = audio_processing_create(&init_config_with_all_enabled(), &mut error);
208 assert!(!ap.is_null());
209 assert!(is_success(error));
210
211 let config = config_with_all_enabled();
212 set_config(ap, &config);
213
214 let mut frame = vec![vec![0f32; NUM_SAMPLES_PER_FRAME as usize]; 1];
215 let mut frame_ptr = frame.iter_mut().map(|v| v.as_mut_ptr()).collect::<Vec<*mut f32>>();
216 assert!(is_success(process_render_frame(ap, frame_ptr.as_mut_ptr())));
217 assert!(is_success(process_capture_frame(ap, frame_ptr.as_mut_ptr())));
218 let stats = get_stats(ap);
219 println!("Stats:\n{:#?}", stats);
220 assert!(stats.has_voice.has_value);
221 assert!(stats.has_echo.has_value);
222 assert!(stats.rms_dbfs.has_value);
223 assert!(stats.speech_probability.has_value);
224 assert!(stats.residual_echo_return_loss.has_value);
225 assert!(stats.echo_return_loss.has_value);
226 assert!(stats.echo_return_loss_enhancement.has_value);
227 assert!(stats.a_nlp.has_value);
228 assert!(stats.delay_median_ms.has_value);
229 assert!(stats.delay_standard_deviation_ms.has_value);
230 assert!(stats.delay_fraction_poor_delays.has_value);
231
232 audio_processing_delete(ap);
233 }
234 }
235}