1#![warn(clippy::all)]
5#![warn(missing_docs)]
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Default, Copy, Clone, PartialEq)]
15#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
17pub struct Config {
18 pub pipeline: Pipeline,
20
21 pub capture_amplifier: Option<CaptureAmplifier>,
23
24 pub high_pass_filter: Option<HighPassFilter>,
27
28 pub echo_canceller: Option<EchoCanceller>,
30
31 pub noise_suppression: Option<NoiseSuppression>,
33
34 pub gain_controller: Option<GainController>,
36}
37
38#[derive(Debug, Default, Copy, Clone, PartialEq)]
40#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
41#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
42pub struct Pipeline {
43 pub maximum_internal_processing_rate: PipelineProcessingRate,
45
46 pub multi_channel_render: bool,
48
49 pub multi_channel_capture: bool,
52
53 pub capture_downmix_method: DownmixMethod,
56}
57
58#[derive(Debug, Copy, Clone, Default, PartialEq)]
60#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
61#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
62#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
63pub enum PipelineProcessingRate {
64 #[cfg_attr(feature = "strum", strum(serialize = "32 kHz"))]
66 Max32000Hz = 32_000,
67
68 #[default]
70 #[cfg_attr(feature = "strum", strum(serialize = "48 kHz"))]
71 Max48000Hz = 48_000,
72}
73
74#[derive(Debug, Copy, Default, Clone, PartialEq, Eq)]
76#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
77#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
78#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
79pub enum DownmixMethod {
80 #[default]
82 Average,
83 #[cfg_attr(feature = "strum", strum(serialize = "Use first channel"))]
85 UseFirstChannel,
86}
87
88#[derive(Debug, Copy, Clone, PartialEq)]
90#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
91#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type"))]
92#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
93pub enum CaptureAmplifier {
94 #[cfg_attr(feature = "strum", strum(serialize = "Pre-amplifier"))]
96 PreAmplifier(PreAmplifier),
97 #[cfg_attr(feature = "strum", strum(serialize = "Capture level adjustment"))]
99 CaptureLevelAdjustment(CaptureLevelAdjustment),
100}
101
102#[derive(Debug, Copy, Clone, PartialEq)]
106#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
107#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
108pub struct PreAmplifier {
109 pub fixed_gain_factor: f32,
111}
112
113impl Default for PreAmplifier {
114 fn default() -> Self {
115 Self { fixed_gain_factor: 1.0 }
116 }
117}
118
119#[derive(Debug, Copy, Clone, PartialEq)]
122#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
123#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
124pub struct CaptureLevelAdjustment {
125 pub pre_gain_factor: f32,
127
128 pub post_gain_factor: f32,
130
131 pub analog_mic_gain_emulation: Option<AnalogMicGainEmulation>,
133}
134
135impl Default for CaptureLevelAdjustment {
136 fn default() -> Self {
137 Self { pre_gain_factor: 1.0, post_gain_factor: 1.0, analog_mic_gain_emulation: None }
138 }
139}
140
141#[derive(Debug, Copy, Clone, PartialEq)]
143#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
144#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
145pub struct AnalogMicGainEmulation {
146 pub initial_level: u8,
149}
150
151impl Default for AnalogMicGainEmulation {
152 fn default() -> Self {
153 Self { initial_level: 255 }
154 }
155}
156
157#[derive(Debug, Copy, Clone, PartialEq)]
159#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
160#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
161pub struct HighPassFilter {
162 pub apply_in_full_band: bool,
164}
165
166impl Default for HighPassFilter {
167 fn default() -> Self {
168 Self { apply_in_full_band: true }
169 }
170}
171
172#[derive(Debug, Copy, Clone, PartialEq)]
178#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
179#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type"))]
180#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
181pub enum EchoCanceller {
182 #[cfg_attr(feature = "strum", strum(serialize = "Mobile (AECM)"))]
185 Mobile {
186 stream_delay_ms: u16,
189 },
190
191 #[cfg_attr(feature = "strum", strum(serialize = "Full (AEC3)"))]
193 Full {
194 stream_delay_ms: Option<u16>,
197 },
198}
199
200impl Default for EchoCanceller {
201 fn default() -> Self {
202 Self::Full { stream_delay_ms: None }
203 }
204}
205
206#[derive(Debug, Copy, Clone, PartialEq)]
208#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
209#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
210pub struct NoiseSuppression {
211 pub level: NoiseSuppressionLevel,
214
215 pub analyze_linear_aec_output: bool,
219}
220
221impl Default for NoiseSuppression {
222 fn default() -> Self {
223 Self { level: NoiseSuppressionLevel::Moderate, analyze_linear_aec_output: false }
224 }
225}
226
227#[derive(Debug, Copy, Clone, PartialEq)]
229#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
230#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
231#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
232pub enum NoiseSuppressionLevel {
233 Low,
235 Moderate,
237 High,
239 #[cfg_attr(feature = "strum", strum(serialize = "Very High"))]
241 VeryHigh,
242}
243
244#[derive(Debug, Copy, Clone, PartialEq)]
246#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
247#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type"))]
248#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
249pub enum GainController {
250 #[cfg_attr(feature = "strum", strum(serialize = "Gain Controller 1"))]
252 GainController1(GainController1),
253 #[cfg_attr(feature = "strum", strum(serialize = "Gain Controller 2"))]
255 GainController2(GainController2),
256}
257
258#[derive(Debug, Copy, Clone, PartialEq)]
265#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
267pub struct GainController1 {
268 pub mode: GainControllerMode,
270
271 pub target_level_dbfs: u8,
276
277 pub compression_gain_db: u8,
284
285 pub enable_limiter: bool,
289
290 pub analog_gain_controller: Option<AnalogGainController>,
292}
293
294impl Default for GainController1 {
295 fn default() -> Self {
296 Self {
297 mode: GainControllerMode::AdaptiveAnalog,
298 target_level_dbfs: 3,
299 compression_gain_db: 9,
300 enable_limiter: true,
301 analog_gain_controller: None,
302 }
303 }
304}
305
306#[derive(Debug, Copy, Clone, PartialEq)]
308#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
309#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
310#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
311pub enum GainControllerMode {
312 #[cfg_attr(feature = "strum", strum(serialize = "Adaptive Analog"))]
319 AdaptiveAnalog,
320 #[cfg_attr(feature = "strum", strum(serialize = "Adaptive Digital"))]
326 AdaptiveDigital,
327 #[cfg_attr(feature = "strum", strum(serialize = "Fixed Digital"))]
336 FixedDigital,
337}
338
339#[derive(Debug, Copy, Clone, PartialEq)]
341#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
342#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
343pub struct AnalogGainController {
344 pub startup_min_volume: i32,
346 pub clipped_level_min: i32,
349 pub enable_digital_adaptive: bool,
351 pub clipped_level_step: i32,
354 pub clipped_ratio_threshold: f32,
357 pub clipped_wait_frames: i32,
360 pub clipping_predictor: Option<ClippingPredictor>,
362}
363
364impl Default for AnalogGainController {
365 fn default() -> Self {
366 Self {
367 startup_min_volume: 0,
368 clipped_level_min: 70,
369 enable_digital_adaptive: true,
370 clipped_level_step: 15,
371 clipped_ratio_threshold: 0.1,
372 clipped_wait_frames: 300,
373 clipping_predictor: None,
374 }
375 }
376}
377
378#[derive(Debug, Copy, Clone, PartialEq)]
380#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
381#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
382pub struct ClippingPredictor {
383 pub mode: ClippingPredictorMode,
385 pub window_length: i32,
387 pub reference_window_length: i32,
389 pub reference_window_delay: i32,
391 pub clipping_threshold: f32,
393 pub crest_factor_margin: f32,
395 pub use_predicted_step: bool,
399}
400
401impl Default for ClippingPredictor {
402 fn default() -> Self {
403 Self {
404 mode: ClippingPredictorMode::ClippingEventPrediction,
405 window_length: 5,
406 reference_window_length: 5,
407 reference_window_delay: 5,
408 clipping_threshold: -1.0,
409 crest_factor_margin: 3.0,
410 use_predicted_step: true,
411 }
412 }
413}
414
415#[derive(Debug, Copy, Clone, PartialEq)]
417#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
418#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
419#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
420pub enum ClippingPredictorMode {
421 #[cfg_attr(feature = "strum", strum(serialize = "Clipping Event Prediction"))]
423 ClippingEventPrediction,
424 #[cfg_attr(feature = "strum", strum(serialize = "Adaptive Step Clipping Peak Prediction"))]
426 AdaptiveStepClippingPeakPrediction,
427 #[cfg_attr(feature = "strum", strum(serialize = "Fixed Step Clipping Peak Prediction"))]
429 FixedStepClippingPeakPrediction,
430}
431
432#[derive(Debug, Copy, Default, Clone, PartialEq)]
438#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
439#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
440pub struct GainController2 {
441 pub input_volume_controller_enabled: bool,
445 pub adaptive_digital: Option<AdaptiveDigital>,
449 pub fixed_digital: FixedDigital,
453}
454
455#[derive(Debug, Copy, Clone, PartialEq)]
459#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
460#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
461pub struct AdaptiveDigital {
462 pub headroom_db: f32,
464 pub max_gain_db: f32,
466 pub initial_gain_db: f32,
468 pub max_gain_change_db_per_second: f32,
470 pub max_output_noise_level_dbfs: f32,
472}
473
474impl Default for AdaptiveDigital {
475 fn default() -> Self {
476 Self {
477 headroom_db: 5.0,
478 max_gain_db: 50.0,
479 initial_gain_db: 15.0,
480 max_gain_change_db_per_second: 6.0,
481 max_output_noise_level_dbfs: -50.0,
482 }
483 }
484}
485
486#[derive(Debug, Copy, Clone, PartialEq)]
490#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
491#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
492pub struct FixedDigital {
493 pub gain_db: f32,
496}
497
498impl Default for FixedDigital {
499 fn default() -> Self {
500 Self { gain_db: 0.0 }
501 }
502}