audio_processor/
processing.rs

1use std::time::Duration;
2use crate::errors::AudioError;
3
4/// Enum for available audio effects.
5#[derive(Debug)]
6pub enum AudioEffect {
7    FadeIn(Duration),
8    FadeOut(Duration),
9    Echo { delay: Duration, decay: f32 },
10    // Additional effects (e.g., reverb) can be added here.
11}
12
13/// Converts an AudioEffect into an FFmpeg filter string.
14pub fn effect_to_filter(effect: &AudioEffect) -> String {
15    match effect {
16        AudioEffect::FadeIn(dur) => {
17            // The afade filter: type=in, start_time=0, duration=dur
18            format!("afade=t=in:st=0:d={}", dur.as_secs_f32())
19        }
20        AudioEffect::FadeOut(dur) => {
21            // Assuming fade out at the end (this is a simplification)
22            format!("afade=t=out:st=0:d={}", dur.as_secs_f32())
23        }
24        AudioEffect::Echo { delay, decay } => {
25            // Using a simple aecho filter.
26            // Format: aecho=in_gain:out_gain:delays:decays
27            format!("aecho=0.8:0.9:{}:{}", delay.as_millis(), decay)
28        }
29    }
30}
31
32/// Reverses an audio file using FFmpeg’s areverse filter.
33pub fn reverse_audio(input_path: &str, output_path: &str) -> Result<(), AudioError> {
34    println!("Reversing audio: {} -> {}", input_path, output_path);
35    let status = std::process::Command::new("ffmpeg")
36        .args(&["-i", input_path, "-af", "areverse", output_path, "-y"])
37        .status()
38        .map_err(|e| AudioError::IoError(e))?;
39    if status.success() {
40        Ok(())
41    } else {
42        Err(AudioError::FfmpegError("ffmpeg reverse failed".to_string()))
43    }
44}
45
46/// Normalizes the audio volume using FFmpeg’s loudnorm filter.
47pub fn normalize_volume(input_path: &str, output_path: &str) -> Result<(), AudioError> {
48    println!("Normalizing volume: {} -> {}", input_path, output_path);
49    let status = std::process::Command::new("ffmpeg")
50        .args(&["-i", input_path, "-af", "loudnorm", output_path, "-y"])
51        .status()
52        .map_err(|e| AudioError::IoError(e))?;
53    if status.success() {
54        Ok(())
55    } else {
56        Err(AudioError::FfmpegError("ffmpeg normalize failed".to_string()))
57    }
58}