extern crate portaudio;
use portaudio as pa;
use std::collections::VecDeque;
const SAMPLE_RATE: f64 = 44_100.0;
const CHANNELS: i32 = 2;
const FRAMES: u32 = 256;
const INTERLEAVED: bool = true;
fn main() {
match run() {
Ok(_) => {}
e => {
eprintln!("Example failed with the following: {:?}", e);
}
}
}
fn run() -> Result<(), pa::Error> {
let pa = pa::PortAudio::new()?;
println!("PortAudio");
println!("version: {}", pa.version());
println!("version text: {:?}", pa.version_text());
println!("host count: {}", pa.host_api_count()?);
let default_host = pa.default_host_api()?;
println!("default host: {:#?}", pa.host_api_info(default_host));
let def_input = pa.default_input_device()?;
let input_info = pa.device_info(def_input)?;
println!("Default input device info: {:#?}", &input_info);
let latency = input_info.default_low_input_latency;
let input_params = pa::StreamParameters::<f32>::new(def_input, CHANNELS, INTERLEAVED, latency);
let def_output = pa.default_output_device()?;
let output_info = pa.device_info(def_output)?;
println!("Default output device info: {:#?}", &output_info);
let latency = output_info.default_low_output_latency;
let output_params =
pa::StreamParameters::<f32>::new(def_output, CHANNELS, INTERLEAVED, latency);
pa.is_duplex_format_supported(input_params, output_params, SAMPLE_RATE)?;
let settings = pa::DuplexStreamSettings::new(input_params, output_params, SAMPLE_RATE, FRAMES);
let mut stream = pa.open_blocking_stream(settings)?;
let mut buffer: VecDeque<f32> = VecDeque::with_capacity(FRAMES as usize * CHANNELS as usize);
stream.start()?;
fn wait_for_stream<F>(f: F, name: &str) -> u32
where
F: Fn() -> Result<pa::StreamAvailable, pa::error::Error>,
{
loop {
match f() {
Ok(available) => match available {
pa::StreamAvailable::Frames(frames) => return frames as u32,
pa::StreamAvailable::InputOverflowed => println!("Input stream has overflowed"),
pa::StreamAvailable::OutputUnderflowed => {
println!("Output stream has underflowed")
}
},
Err(err) => panic!(
"An error occurred while waiting for the {} stream: {}",
name, err
),
}
}
}
loop {
let in_frames = wait_for_stream(|| stream.read_available(), "Read");
if in_frames > 0 {
let input_samples = stream.read(in_frames)?;
buffer.extend(input_samples.into_iter());
println!("Read {:?} frames from the input stream.", in_frames);
}
let out_frames = wait_for_stream(|| stream.write_available(), "Write");
let buffer_frames = (buffer.len() / CHANNELS as usize) as u32;
if out_frames > 0 && buffer_frames > 0 {
let write_frames = if buffer_frames >= out_frames {
out_frames
} else {
buffer_frames
};
let n_write_samples = write_frames as usize * CHANNELS as usize;
stream.write(write_frames, |output| {
for i in 0..n_write_samples {
output[i] = buffer.pop_front().unwrap();
}
println!("Wrote {:?} frames to the output stream.", out_frames);
})?;
}
}
}