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

Upgrade webrtc-audio-processing lib to v1.3 #23

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "webrtc-audio-processing"
version = "0.4.0"
version = "0.5.0"
authors = ["Ryo Kawaguchi <[email protected]>"]
repository = "https://github.com/tonarino/webrtc-audio-processing"
edition = "2018"
Expand All @@ -20,18 +20,18 @@ bundled = ["webrtc-audio-processing-sys/bundled"]

[dependencies]
serde = { version = "1", features = ["derive"], optional = true }
webrtc-audio-processing-sys = { path = "webrtc-audio-processing-sys", version = "0.4.0" }
webrtc-audio-processing-sys = { path = "webrtc-audio-processing-sys", version = "0.5.0" }

[[example]]
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