use crate::contracts::{AudioProcessor, ProcessorBuildRequest, ProcessorFactory};
use crate::core::AudioResult;
use crate::profiles::build_processors;
pub struct ProfileProcessorFactory;
impl ProfileProcessorFactory {
pub fn new() -> Self {
Self
}
}
impl Default for ProfileProcessorFactory {
fn default() -> Self {
Self::new()
}
}
impl ProcessorFactory for ProfileProcessorFactory {
fn build_processors(
&self,
request: ProcessorBuildRequest,
) -> AudioResult<Vec<Box<dyn AudioProcessor>>> {
build_processors(
request.profile,
request.gain_db,
request.limiter_threshold,
request.high_pass_hz,
request.noise_suppression_amount,
request.noise_calibration_ms,
request.delay_effect,
&request.stage_overrides,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::{AudioProfile, DelayEffectConfig, DelayEffectPreset};
use std::collections::BTreeMap;
#[test]
fn factory_builds_expected_hvac_chain() {
let factory = ProfileProcessorFactory::new();
let processors = factory
.build_processors(ProcessorBuildRequest {
profile: AudioProfile::VoiceHvac,
gain_db: 2.0,
limiter_threshold: 0.92,
high_pass_hz: 100.0,
noise_suppression_amount: 0.5,
noise_calibration_ms: 350,
delay_effect: None,
stage_overrides: BTreeMap::new(),
})
.unwrap();
let names = processors.iter().map(|p| p.name()).collect::<Vec<_>>();
assert_eq!(
names,
vec![
"high_pass",
"low_shelf_cut",
"low_pass",
"expander",
"noise_suppression",
"adaptive_gain",
"compressor",
"agc",
"adaptive_tone_shaper",
"mid_resonance_suppressor",
"high_band_cleanup",
"presence_boost",
"deesser",
"tail_suppression",
"air_band_reducer",
"voice_finisher",
"limiter"
]
);
}
#[test]
fn factory_builds_raw_profile_without_processors() {
let factory = ProfileProcessorFactory::new();
let processors = factory
.build_processors(ProcessorBuildRequest {
profile: AudioProfile::Raw,
gain_db: 0.0,
limiter_threshold: 0.92,
high_pass_hz: 0.0,
noise_suppression_amount: 0.0,
noise_calibration_ms: 0,
delay_effect: None,
stage_overrides: BTreeMap::new(),
})
.unwrap();
assert!(processors.is_empty());
}
#[test]
fn factory_builds_delay_stage_before_limiter_when_enabled() {
let factory = ProfileProcessorFactory::new();
let processors = factory
.build_processors(ProcessorBuildRequest {
profile: AudioProfile::VoiceClean,
gain_db: 2.0,
limiter_threshold: 0.92,
high_pass_hz: 100.0,
noise_suppression_amount: 0.5,
noise_calibration_ms: 350,
delay_effect: Some(DelayEffectConfig {
preset: DelayEffectPreset::Slapback,
}),
stage_overrides: BTreeMap::new(),
})
.unwrap();
let names = processors.iter().map(|p| p.name()).collect::<Vec<_>>();
assert_eq!(names[names.len() - 3], "doubling_delay");
assert_eq!(names[names.len() - 2], "voice_finisher");
assert_eq!(names[names.len() - 1], "limiter");
}
}