#![warn(clippy::all)]
#![warn(missing_docs)]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct Config {
pub pipeline: Pipeline,
pub capture_amplifier: Option<CaptureAmplifier>,
pub high_pass_filter: Option<HighPassFilter>,
pub echo_canceller: Option<EchoCanceller>,
pub noise_suppression: Option<NoiseSuppression>,
pub gain_controller: Option<GainController>,
}
#[derive(Debug, Default, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct Pipeline {
pub maximum_internal_processing_rate: PipelineProcessingRate,
pub multi_channel_render: bool,
pub multi_channel_capture: bool,
pub capture_downmix_method: DownmixMethod,
}
#[derive(Debug, Copy, Clone, Default, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
pub enum PipelineProcessingRate {
#[cfg_attr(feature = "strum", strum(serialize = "32 kHz"))]
Max32000Hz = 32_000,
#[default]
#[cfg_attr(feature = "strum", strum(serialize = "48 kHz"))]
Max48000Hz = 48_000,
}
#[derive(Debug, Copy, Default, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
pub enum DownmixMethod {
#[default]
Average,
#[cfg_attr(feature = "strum", strum(serialize = "Use first channel"))]
UseFirstChannel,
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type"))]
#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
pub enum CaptureAmplifier {
#[cfg_attr(feature = "strum", strum(serialize = "Pre-amplifier"))]
PreAmplifier(PreAmplifier),
#[cfg_attr(feature = "strum", strum(serialize = "Capture level adjustment"))]
CaptureLevelAdjustment(CaptureLevelAdjustment),
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct PreAmplifier {
pub fixed_gain_factor: f32,
}
impl Default for PreAmplifier {
fn default() -> Self {
Self { fixed_gain_factor: 1.0 }
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct CaptureLevelAdjustment {
pub pre_gain_factor: f32,
pub post_gain_factor: f32,
pub analog_mic_gain_emulation: Option<AnalogMicGainEmulation>,
}
impl Default for CaptureLevelAdjustment {
fn default() -> Self {
Self { pre_gain_factor: 1.0, post_gain_factor: 1.0, analog_mic_gain_emulation: None }
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct AnalogMicGainEmulation {
pub initial_level: u8,
}
impl Default for AnalogMicGainEmulation {
fn default() -> Self {
Self { initial_level: 255 }
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct HighPassFilter {
pub apply_in_full_band: bool,
}
impl Default for HighPassFilter {
fn default() -> Self {
Self { apply_in_full_band: true }
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type"))]
#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
pub enum EchoCanceller {
#[cfg_attr(feature = "strum", strum(serialize = "Mobile (AECM)"))]
Mobile {
stream_delay_ms: u16,
},
#[cfg_attr(feature = "strum", strum(serialize = "Full (AEC3)"))]
Full {
stream_delay_ms: Option<u16>,
},
}
impl Default for EchoCanceller {
fn default() -> Self {
Self::Full { stream_delay_ms: None }
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct NoiseSuppression {
pub level: NoiseSuppressionLevel,
pub analyze_linear_aec_output: bool,
}
impl Default for NoiseSuppression {
fn default() -> Self {
Self { level: NoiseSuppressionLevel::Moderate, analyze_linear_aec_output: false }
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
pub enum NoiseSuppressionLevel {
Low,
Moderate,
High,
#[cfg_attr(feature = "strum", strum(serialize = "Very High"))]
VeryHigh,
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type"))]
#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
pub enum GainController {
#[cfg_attr(feature = "strum", strum(serialize = "Gain Controller 1"))]
GainController1(GainController1),
#[cfg_attr(feature = "strum", strum(serialize = "Gain Controller 2"))]
GainController2(GainController2),
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct GainController1 {
pub mode: GainControllerMode,
pub target_level_dbfs: u8,
pub compression_gain_db: u8,
pub enable_limiter: bool,
pub analog_gain_controller: Option<AnalogGainController>,
}
impl Default for GainController1 {
fn default() -> Self {
Self {
mode: GainControllerMode::AdaptiveAnalog,
target_level_dbfs: 3,
compression_gain_db: 9,
enable_limiter: true,
analog_gain_controller: None,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
pub enum GainControllerMode {
#[cfg_attr(feature = "strum", strum(serialize = "Adaptive Analog"))]
AdaptiveAnalog,
#[cfg_attr(feature = "strum", strum(serialize = "Adaptive Digital"))]
AdaptiveDigital,
#[cfg_attr(feature = "strum", strum(serialize = "Fixed Digital"))]
FixedDigital,
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct AnalogGainController {
pub startup_min_volume: i32,
pub clipped_level_min: i32,
pub enable_digital_adaptive: bool,
pub clipped_level_step: i32,
pub clipped_ratio_threshold: f32,
pub clipped_wait_frames: i32,
pub clipping_predictor: Option<ClippingPredictor>,
}
impl Default for AnalogGainController {
fn default() -> Self {
Self {
startup_min_volume: 0,
clipped_level_min: 70,
enable_digital_adaptive: true,
clipped_level_step: 15,
clipped_ratio_threshold: 0.1,
clipped_wait_frames: 300,
clipping_predictor: None,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct ClippingPredictor {
pub mode: ClippingPredictorMode,
pub window_length: i32,
pub reference_window_length: i32,
pub reference_window_delay: i32,
pub clipping_threshold: f32,
pub crest_factor_margin: f32,
pub use_predicted_step: bool,
}
impl Default for ClippingPredictor {
fn default() -> Self {
Self {
mode: ClippingPredictorMode::ClippingEventPrediction,
window_length: 5,
reference_window_length: 5,
reference_window_delay: 5,
clipping_threshold: -1.0,
crest_factor_margin: 3.0,
use_predicted_step: true,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumIter))]
pub enum ClippingPredictorMode {
#[cfg_attr(feature = "strum", strum(serialize = "Clipping Event Prediction"))]
ClippingEventPrediction,
#[cfg_attr(feature = "strum", strum(serialize = "Adaptive Step Clipping Peak Prediction"))]
AdaptiveStepClippingPeakPrediction,
#[cfg_attr(feature = "strum", strum(serialize = "Fixed Step Clipping Peak Prediction"))]
FixedStepClippingPeakPrediction,
}
#[derive(Debug, Copy, Default, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct GainController2 {
pub input_volume_controller_enabled: bool,
pub adaptive_digital: Option<AdaptiveDigital>,
pub fixed_digital: FixedDigital,
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct AdaptiveDigital {
pub headroom_db: f32,
pub max_gain_db: f32,
pub initial_gain_db: f32,
pub max_gain_change_db_per_second: f32,
pub max_output_noise_level_dbfs: f32,
}
impl Default for AdaptiveDigital {
fn default() -> Self {
Self {
headroom_db: 5.0,
max_gain_db: 50.0,
initial_gain_db: 15.0,
max_gain_change_db_per_second: 6.0,
max_output_noise_level_dbfs: -50.0,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(default))]
pub struct FixedDigital {
pub gain_db: f32,
}
impl Default for FixedDigital {
fn default() -> Self {
Self { gain_db: 0.0 }
}
}