Untitled
unknown
rust
4 years ago
3.3 kB
9
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...