Untitled
unknown
rust
3 years ago
3.3 kB
7
Indexable
extern crate anyhow; extern crate cpal; extern crate ringbuf; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; // use ringbuf::RingBuffer; use std::f32::consts::PI; #[derive(Debug)] struct Opt { latency: f32, input_device: String, output_device: String, } impl Opt { fn default() -> Self { let latency: f32 = 50.0; let input_device = "default".to_string(); let output_device = "default".to_string(); Opt { latency, input_device, output_device, } } } fn main() -> anyhow::Result<()> { let opt = Opt::default(); let host = cpal::default_host(); // Find devices. let output_device = if opt.output_device == "default" { host.default_output_device() } else { host.output_devices()? .find(|x| x.name().map(|y| y == opt.output_device).unwrap_or(false)) } .expect("failed to find output device"); println!("Using output device: \"{}\"", output_device.name()?); // We'll try and use the same configuration between streams to keep it simple. let config = output_device.default_output_config()?; // let output_data_fn = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| { // for sample in data.chunks_exact_mut(2) { // sample[0] = 0.0; // sample[1] = 0.0; // } // }; // Build streams. println!( "Attempting to build stream with f32 samples and `{:?}`.", config ); assert!(config.sample_format() == cpal::SampleFormat::F32); assert!(config.channels() == 2); let output_stream = run(&output_device, &config.into()).unwrap(); // let output_stream = output_device.build_output_stream(&config, output_data_fn, err_fn)?; // println!("Successfully built streams."); // Play the streams. println!( "Starting the input and output streams with `{}` milliseconds of latency.", opt.latency ); // input_stream.play()?; output_stream.play()?; // Run for 3 seconds before closing. println!("Playing for 3 seconds... "); std::thread::sleep(std::time::Duration::from_secs(3)); // drop(input_stream); drop(output_stream); println!("Done!"); Ok(()) } pub fn run(device: &cpal::Device, config: &cpal::StreamConfig) -> Result<cpal::Stream, anyhow::Error> { let mut audio_closure = build_closure(config); let stream = device.build_output_stream( config, move |buffer: &mut [f32], _: &cpal::OutputCallbackInfo| { audio_closure(buffer); }, err_fn, )?; Ok(stream) } fn build_closure(config: &cpal::StreamConfig) -> impl FnMut(&mut [f32]) { let sample_rate = config.sample_rate.0 as f32; // Callback data let mut accum = 0.0; let freq = 440.0 / sample_rate; move |buffer: &mut [f32]| { for sample in buffer.chunks_mut(2) { accum += freq; accum = accum.fract(); let out = (accum* 2.0 * PI).sin(); sample[0] = out; sample[1] = out; } } } fn err_fn(err: cpal::StreamError) { eprintln!("an error occurred on stream: {}", err); }
Editor is loading...