Skip to content

Commit

Permalink
Upgrade webrtc-audio-processing lib to v1.3 (not tested to build)
Browse files Browse the repository at this point in the history
  • Loading branch information
skywhale committed Jan 7, 2025
1 parent aaae99f commit 35e5e21
Show file tree
Hide file tree
Showing 16 changed files with 759 additions and 1,011 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "webrtc-audio-processing-sys/webrtc-audio-processing"]
path = webrtc-audio-processing-sys/webrtc-audio-processing
url = https://github.com/tonarino/pulseaudio-webrtc-audio-processing.git
url = https://gitlab.freedesktop.org/pulseaudio/webrtc-audio-processing
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ name = "recording"
required-features = ["derive_serde"]

[dev-dependencies]
anyhow = "1"
crossbeam-channel = "0.5"
ctrlc = { version = "3", features = ["termination"] }
failure = "0.1"
hound = "3.4"
json5 = "0.3"
hound = "3"
json5 = "0.4"
portaudio = "0.7"
regex = "1"
serde = { version = "1", features = ["derive"]}
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ The webrtc source code is included as a git submodule. Be sure to clone this rep
Building from source and static linking can be enabled with the `bundled` feature flag. You need the following tools to build from source:

* `clang` or `gcc`
* `autotools` (MacOS: `brew install automake`, `brew install autoconf`)
* `libtoolize` (typically `glibtoolize` on MacOS: `brew install libtool`)
* `pkg-config` (MacOS: `brew install pkg-config`)
* `automake` (MacOS: `brew install automake`)
* `pkg-config` (macOS: `brew install pkg-config`)
* `meson` (masOS: `brew install meson`)
* `ninja` (macOS: `brew install ninja`)
* (to confirm) `autotools` (MacOS: `brew install automake`, `brew install autoconf`)
* (to confirm) `libtoolize` (typically `glibtoolize` on MacOS: `brew install libtool`)
* (to confirm) `automake` (MacOS: `brew install automake`)

## Publishing

Expand Down
25 changes: 8 additions & 17 deletions examples/karaoke.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// This example loops the microphone input back to the speakers, while applying echo cancellation,
// creating an experience similar to Karaoke microphones. It uses PortAudio as an interface to the
// underlying audio devices.
use anyhow::Error;
use ctrlc;
use failure::Error;
use portaudio;
use std::{
sync::{
Expand All @@ -21,26 +21,17 @@ const SAMPLE_RATE: f64 = 48_000.0;
const FRAMES_PER_BUFFER: u32 = 480;

fn create_processor(
num_capture_channels: i32,
num_render_channels: i32,
num_capture_channels: usize,
num_render_channels: usize,
) -> Result<Processor, Error> {
let mut processor = Processor::new(&InitializationConfig {
num_capture_channels,
num_render_channels,
..InitializationConfig::default()
sample_rate_hz: SAMPLE_RATE as u32,
})?;

// High pass filter is a prerequisite to running echo cancellation.
let config = Config {
echo_cancellation: Some(EchoCancellation {
suppression_level: EchoCancellationSuppressionLevel::Low,
stream_delay_ms: Some(0),
enable_delay_agnostic: true,
enable_extended_filter: true,
}),
enable_high_pass_filter: true,
..Config::default()
};
// The default AEC configuration enables HPF, too.
let config = Config { echo_canceller: Some(EchoCanceller::default()), ..Config::default() };
processor.set_config(config);

Ok(processor)
Expand Down Expand Up @@ -74,8 +65,8 @@ fn main() -> Result<(), Error> {
let pa = portaudio::PortAudio::new()?;

let stream_settings = pa.default_duplex_stream_settings(
input_channels,
output_channels,
input_channels as i32,
output_channels as i32,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
)?;
Expand Down
19 changes: 10 additions & 9 deletions examples/recording.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
/// $ cargo run --example recording --features bundled --features derive_serde -- --config-file \
/// examples/recording-configs/record-pipeline.json5
/// ```
use failure::{format_err, Error};
use anyhow::{anyhow, Error};
use hound::{WavIntoSamples, WavReader, WavWriter};
use regex::Regex;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -96,11 +96,12 @@ fn match_device(
return Ok(device.0);
}
}
Err(format_err!("Audio device matching \"{}\" not found.", device_name))
Err(anyhow!("Audio device matching \"{}\" not found.", device_name))
}

fn create_stream_settings(
pa: &portaudio::PortAudio,
processor: &Processor,
opt: &Options,
) -> Result<portaudio::DuplexStreamSettings<f32, f32>, Error> {
let input_device = match_device(pa, Regex::new(&opt.capture.device_name)?)?;
Expand All @@ -127,7 +128,7 @@ fn create_stream_settings(
input_params,
output_params,
f64::from(AUDIO_SAMPLE_RATE),
NUM_SAMPLES_PER_FRAME as u32,
processor.num_samples_per_frame() as u32,
))
}

Expand Down Expand Up @@ -181,9 +182,9 @@ fn main() -> Result<(), Error> {
let pa = portaudio::PortAudio::new()?;

let mut processor = Processor::new(&InitializationConfig {
num_capture_channels: opt.capture.num_channels as i32,
num_render_channels: opt.render.num_channels as i32,
..Default::default()
num_capture_channels: opt.capture.num_channels as usize,
num_render_channels: opt.render.num_channels as usize,
sample_rate_hz: AUDIO_SAMPLE_RATE,
})?;

processor.set_config(opt.config.clone());
Expand All @@ -208,13 +209,13 @@ fn main() -> Result<(), Error> {
let audio_callback = {
// Allocate buffers outside the performance-sensitive audio loop.
let mut input_mut =
vec![0f32; NUM_SAMPLES_PER_FRAME as usize * opt.capture.num_channels as usize];
vec![0f32; processor.num_samples_per_frame() * opt.capture.num_channels as usize];

let running = running.clone();
let mute = opt.render.mute;
let mut processor = processor.clone();
move |portaudio::DuplexStreamCallbackArgs { in_buffer, out_buffer, frames, .. }| {
assert_eq!(frames, NUM_SAMPLES_PER_FRAME as usize);
assert_eq!(frames, processor.num_samples_per_frame());

let mut should_continue = true;

Expand Down Expand Up @@ -263,7 +264,7 @@ fn main() -> Result<(), Error> {
}
};

let stream_settings = create_stream_settings(&pa, &opt)?;
let stream_settings = create_stream_settings(&pa, &processor, &opt)?;
let mut stream = pa.open_non_blocking_stream(stream_settings, audio_callback)?;
stream.start()?;

Expand Down
18 changes: 5 additions & 13 deletions examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,17 @@ fn main() {
let config = InitializationConfig {
num_capture_channels: 2, // Stereo mic input
num_render_channels: 2, // Stereo speaker output
..InitializationConfig::default()
sample_rate_hz: 48_000, // The maximum processing rate
};

let mut ap = Processor::new(&config).unwrap();

let config = Config {
echo_cancellation: Some(EchoCancellation {
suppression_level: EchoCancellationSuppressionLevel::High,
enable_delay_agnostic: false,
enable_extended_filter: false,
stream_delay_ms: None,
}),
..Config::default()
};
let config = Config { echo_canceller: Some(EchoCanceller::default()), ..Default::default() };
ap.set_config(config);

// The render_frame is what is sent to the speakers, and
// capture_frame is audio captured from a microphone.
let (render_frame, capture_frame) = sample_stereo_frames();
let (render_frame, capture_frame) = sample_stereo_frames(&ap);

let mut render_frame_output = render_frame.clone();
ap.process_render_frame(&mut render_frame_output).unwrap();
Expand All @@ -43,8 +35,8 @@ fn main() {

/// Generate example stereo frames that simulates a situation where the
/// microphone (capture) would be picking up the speaker (render) output.
fn sample_stereo_frames() -> (Vec<f32>, Vec<f32>) {
let num_samples_per_frame = NUM_SAMPLES_PER_FRAME as usize;
fn sample_stereo_frames(processor: &Processor) -> (Vec<f32>, Vec<f32>) {
let num_samples_per_frame = processor.num_samples_per_frame();

let mut render_frame = Vec::with_capacity(num_samples_per_frame * 2);
let mut capture_frame = Vec::with_capacity(num_samples_per_frame * 2);
Expand Down
Loading

0 comments on commit 35e5e21

Please sign in to comment.