Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage #41

Open
thewh1teagle opened this issue Dec 6, 2024 · 0 comments
Open

Usage #41

thewh1teagle opened this issue Dec 6, 2024 · 0 comments

Comments

@thewh1teagle
Copy link

thewh1teagle commented Dec 6, 2024

Hey
I'm trying to use this library for echo cancellation like this example in aec-rs crate:
https://github.com/thewh1teagle/aec-rs/blob/main/examples/wav.rs
But I don't understand how to use it that way.

I tried the following but it doesn't cancel the echo

/*
wget https://github.com/thewh1teagle/aec-rs/releases/download/audio-files/rec.wav
wget https://github.com/thewh1teagle/aec-rs/releases/download/audio-files/echo.wav
wget https://github.com/thewh1teagle/aec-rs/releases/download/audio-files/voice.wav
cargo run --example wav rec.wav echo.wav cancelled.wav
*/

use hound;
use webrtc_audio_processing::*;

const SAMPLE_RATE: f64 = 16_000.0; // 16kHz
const FRAMES_PER_BUFFER: u32 = 480; // 10ms per buffer

fn create_processor() -> Result<Processor, Box<dyn std::error::Error>> {
    let mut processor = Processor::new(&InitializationConfig {
        num_capture_channels: 1,
        num_render_channels: 1,
        ..InitializationConfig::default()
    })?;

    let config = Config {
        echo_cancellation: Some(EchoCancellation {
            suppression_level: EchoCancellationSuppressionLevel::High,
            stream_delay_ms: Some(0),
            enable_delay_agnostic: false,
            enable_extended_filter: false,
        }),
        enable_high_pass_filter: false,
        ..Config::default()
    };
    processor.set_config(config);

    Ok(processor)
}

fn main() {
    let rec_path = std::env::args().nth(1).expect("Please specify echo path");
    let echo_path = std::env::args().nth(2).expect("Please specify rec path");
    let out_path = std::env::args().nth(3).expect("Please specify out path");

    // Read echo samples
    let mut reader = hound::WavReader::open(echo_path).unwrap();
    let echo_samples: Vec<f32> = reader.samples::<i16>()
        .map(|s| s.unwrap() as f32 / i16::MAX as f32)  // Convert i16 to f32 (normalize)
        .collect();

    // Read recorded samples
    let mut reader = hound::WavReader::open(rec_path).unwrap();
    let rec_samples: Vec<f32> = reader.samples::<i16>()
        .map(|s| s.unwrap() as f32 / i16::MAX as f32)  // Convert i16 to f32 (normalize)
        .collect();

    let mut processor = create_processor().unwrap();

    let frame_size = FRAMES_PER_BUFFER as usize;

    // Prepare output WAV writer
    let spec = hound::WavSpec {
        channels: 1,
        sample_rate: SAMPLE_RATE as u32,
        bits_per_sample: 16,
        sample_format: hound::SampleFormat::Int,
    };
    let mut writer = hound::WavWriter::create(&out_path, spec).unwrap();

    let mut output_samples = Vec::new();
    let mut input_frame = vec![0f32; frame_size];
    let mut reference_frame = vec![0f32; frame_size];

    // Process samples frame by frame
    for i in (0..rec_samples.len()).step_by(frame_size) {
        let end = usize::min(i + frame_size, rec_samples.len());

        // Fill frames with input and reference samples
        input_frame[..end - i].copy_from_slice(&rec_samples[i..end]);
        reference_frame[..end - i].copy_from_slice(&echo_samples[i..end]);

        // Apply echo cancellation using webrtc-audio-processing
        processor.process_capture_frame(&mut input_frame).unwrap();
        processor.process_render_frame(&mut reference_frame).unwrap();

        // Convert the output back to i16 and write to the output file
        for &sample in &input_frame {
            writer.write_sample((sample * i16::MAX as f32) as i16).unwrap();
        }

        // Add to output_samples
        output_samples.extend_from_slice(&input_frame);
    }

    println!("Created {}", out_path);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant