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,
221}
222
223impl Default for NoiseSuppression {
224 fn default() -> Self {
225 Self { level: NoiseSuppressionLevel::Moderate, analyze_linear_aec_output: false }
226 }
227}
228
229#[derive(Debug, Copy, Clone, PartialEq)]
231#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
232#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
233#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
234pub enum NoiseSuppressionLevel {
235 Low,
237 Moderate,
239 High,
241 #[cfg_attr(feature = "strum", strum(serialize = "Very High"))]
243 VeryHigh,
244}
245
246#[derive(Debug, Copy, Clone, PartialEq)]
248#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
249#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type"))]
250#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
251pub enum GainController {
252 #[cfg_attr(feature = "strum", strum(serialize = "Gain Controller 1"))]
254 GainController1(GainController1),
255 #[cfg_attr(feature = "strum", strum(serialize = "Gain Controller 2"))]
257 GainController2(GainController2),
258}
259
260#[derive(Debug, Copy, Clone, PartialEq)]
267#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
268#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
269pub struct GainController1 {
270 pub mode: GainControllerMode,
272
273 pub target_level_dbfs: u8,
278
279 pub compression_gain_db: u8,
286
287 pub enable_limiter: bool,
291
292 pub analog_gain_controller: Option<AnalogGainController>,
294}
295
296impl Default for GainController1 {
297 fn default() -> Self {
298 Self {
299 mode: GainControllerMode::AdaptiveAnalog,
300 target_level_dbfs: 3,
301 compression_gain_db: 9,
302 enable_limiter: true,
303 analog_gain_controller: None,
304 }
305 }
306}
307
308#[derive(Debug, Copy, Clone, PartialEq)]
310#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
311#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
312#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
313pub enum GainControllerMode {
314 #[cfg_attr(feature = "strum", strum(serialize = "Adaptive Analog"))]
321 AdaptiveAnalog,
322 #[cfg_attr(feature = "strum", strum(serialize = "Adaptive Digital"))]
328 AdaptiveDigital,
329 #[cfg_attr(feature = "strum", strum(serialize = "Fixed Digital"))]
338 FixedDigital,
339}
340
341#[derive(Debug, Copy, Clone, PartialEq)]
343#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
344#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
345pub struct AnalogGainController {
346 pub startup_min_volume: i32,
348 pub clipped_level_min: i32,
351 pub enable_digital_adaptive: bool,
353 pub clipped_level_step: i32,
356 pub clipped_ratio_threshold: f32,
359 pub clipped_wait_frames: i32,
362 pub clipping_predictor: Option<ClippingPredictor>,
364}
365
366impl Default for AnalogGainController {
367 fn default() -> Self {
368 Self {
369 startup_min_volume: 0,
370 clipped_level_min: 70,
371 enable_digital_adaptive: true,
372 clipped_level_step: 15,
373 clipped_ratio_threshold: 0.1,
374 clipped_wait_frames: 300,
375 clipping_predictor: None,
376 }
377 }
378}
379
380#[derive(Debug, Copy, Clone, PartialEq)]
382#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
383#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
384pub struct ClippingPredictor {
385 pub mode: ClippingPredictorMode,
387 pub window_length: i32,
389 pub reference_window_length: i32,
391 pub reference_window_delay: i32,
393 pub clipping_threshold: f32,
395 pub crest_factor_margin: f32,
397 pub use_predicted_step: bool,
401}
402
403impl Default for ClippingPredictor {
404 fn default() -> Self {
405 Self {
406 mode: ClippingPredictorMode::ClippingEventPrediction,
407 window_length: 5,
408 reference_window_length: 5,
409 reference_window_delay: 5,
410 clipping_threshold: -1.0,
411 crest_factor_margin: 3.0,
412 use_predicted_step: true,
413 }
414 }
415}
416
417#[derive(Debug, Copy, Clone, PartialEq)]
419#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
420#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
421#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
422pub enum ClippingPredictorMode {
423 #[cfg_attr(feature = "strum", strum(serialize = "Clipping Event Prediction"))]
425 ClippingEventPrediction,
426 #[cfg_attr(feature = "strum", strum(serialize = "Adaptive Step Clipping Peak Prediction"))]
428 AdaptiveStepClippingPeakPrediction,
429 #[cfg_attr(feature = "strum", strum(serialize = "Fixed Step Clipping Peak Prediction"))]
431 FixedStepClippingPeakPrediction,
432}
433
434#[derive(Debug, Copy, Default, Clone, PartialEq)]
440#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
441#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
442pub struct GainController2 {
443 pub input_volume_controller_enabled: bool,
447 pub adaptive_digital: Option<AdaptiveDigital>,
451 pub fixed_digital: FixedDigital,
455}
456
457#[derive(Debug, Copy, Clone, PartialEq)]
461#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
462#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
463pub struct AdaptiveDigital {
464 pub headroom_db: f32,
466 pub max_gain_db: f32,
468 pub initial_gain_db: f32,
470 pub max_gain_change_db_per_second: f32,
472 pub max_output_noise_level_dbfs: f32,
474}
475
476impl Default for AdaptiveDigital {
477 fn default() -> Self {
478 Self {
479 headroom_db: 5.0,
480 max_gain_db: 50.0,
481 initial_gain_db: 15.0,
482 max_gain_change_db_per_second: 6.0,
483 max_output_noise_level_dbfs: -50.0,
484 }
485 }
486}
487
488#[derive(Debug, Copy, Clone, PartialEq)]
492#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
493#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
494pub struct FixedDigital {
495 pub gain_db: f32,
498}
499
500impl Default for FixedDigital {
501 fn default() -> Self {
502 Self { gain_db: 0.0 }
503 }
504}