Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use cpal::traits::{DeviceTrait, EventLoopTrait, HostTrait};
- use sample::{ring_buffer, interpolate, signal, Sample, Signal};
- fn main() -> Result<(), failure::Error> {
- let host = cpal::default_host();
- let event_loop = host.event_loop();
- // Default devices.
- let input_device = host.default_input_device().expect("failed to get default input device");
- let output_device = host.default_output_device().expect("failed to get default output device");
- println!("Using default input device: \"{}\"", input_device.name()?);
- println!("Using default output device: \"{}\"", output_device.name()?);
- // We'll try and use the same format between streams to keep it simple
- let mut input_format = input_device.default_input_format()?;
- input_format.data_type = cpal::SampleFormat::I16;
- input_format.channels = 1;
- let mut output_format = output_device.default_output_format()?;
- output_format.data_type = cpal::SampleFormat::I16;
- output_format.channels = 1;
- // Build streams.
- println!("Attempting to build both streams with `{:?}`|`{:?}`.", input_format, output_format);
- let input_stream_id = event_loop.build_input_stream(&input_device, &input_format)?;
- let output_stream_id = event_loop.build_output_stream(&output_device, &output_format)?;
- println!("Successfully built streams.");
- // The channel to share samples.
- let (tx, rx) = std::sync::mpsc::sync_channel(48000);
- // Play the streams.
- println!("Starting the input and output streams.");
- event_loop.play_stream(input_stream_id.clone())?;
- event_loop.play_stream(output_stream_id.clone())?;
- let ring_buffer = ring_buffer::Fixed::from([[0.0]; 100]);
- let sinc = interpolate::Sinc::new(ring_buffer);
- let signal = signal::from_iter(rx.try_iter());
- let mut new_signal = signal.from_hz_to_hz(sinc, input_format.sample_rate.0 as f64, output_format.sample_rate.0 as f64);
- event_loop.run(move |id, result| {
- let data = match result {
- Ok(data) => data,
- Err(err) => {
- eprintln!("an error occurred on stream {:?}: {}", id, err);
- return;
- }
- };
- match data {
- cpal::StreamData::Input { buffer: cpal::UnknownTypeInputBuffer::I16(buffer) } => {
- assert_eq!(id, input_stream_id);
- let mut output_fell_behind = false;
- for &sample in buffer.iter() {
- let frame = [sample.to_sample::<f64>()];
- if tx.try_send(frame).is_err() {
- output_fell_behind = true;
- }
- }
- if output_fell_behind {
- eprintln!("output stream fell behind: try increasing latency");
- }
- },
- cpal::StreamData::Output { buffer: cpal::UnknownTypeOutputBuffer::I16(mut buffer) } => {
- assert_eq!(id, output_stream_id);
- let mut input_fell_behind = None;
- for sample in buffer.iter_mut() {
- *sample = match signal.is_exhausted() {
- false => new_signal.next()[0].to_sample::<i16>(),
- true => {
- input_fell_behind = Some("whoops");
- new_signal.next()[0].to_sample::<i16>()
- },
- };
- }
- if let Some(err) = input_fell_behind {
- eprintln!("input stream fell behind: {}: try increasing latency", err);
- }
- },
- _ => panic!("we're expecting i16 data"),
- }
- })
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement