use anyhow; use cpal::{ traits::{DeviceTrait, HostTrait, StreamTrait}, FromSample, SizedSample, }; use lyd::*; fn main() -> anyhow::Result<()> { let host = cpal::default_host(); let device = host .default_output_device() .expect("failed to find output device"); println!("Output device: {}", device.name()?); let config = device.default_output_config().unwrap(); println!("Default output config: {:?}", config); match config.sample_format() { cpal::SampleFormat::I8 => run::(&device, &config.into()), cpal::SampleFormat::I16 => run::(&device, &config.into()), // cpal::SampleFormat::I24 => run::(&device, &config.into()), cpal::SampleFormat::I32 => run::(&device, &config.into()), // cpal::SampleFormat::I48 => run::(&device, &config.into()), cpal::SampleFormat::I64 => run::(&device, &config.into()), cpal::SampleFormat::U8 => run::(&device, &config.into()), cpal::SampleFormat::U16 => run::(&device, &config.into()), // cpal::SampleFormat::U24 => run::(&device, &config.into()), cpal::SampleFormat::U32 => run::(&device, &config.into()), // cpal::SampleFormat::U48 => run::(&device, &config.into()), cpal::SampleFormat::U64 => run::(&device, &config.into()), cpal::SampleFormat::F32 => run::(&device, &config.into()), cpal::SampleFormat::F64 => run::(&device, &config.into()), sample_format => panic!("Unsupported sample format '{sample_format}'"), } } const BLOCK_SIZE: usize = 128; pub fn run(device: &cpal::Device, config: &cpal::StreamConfig) -> Result<(), anyhow::Error> where T: SizedSample + FromSample, { let sample_rate = config.sample_rate.0; let channels = config.channels as usize; let mut ctx = context() .channels(channels) .frames(BLOCK_SIZE) .sr(sample_rate) .build(&[ ("~mod", &[sin_osc().freq(10.0).amp(300.), add(500.1)]), ("out", &[sin_osc().freq("~mod"), add(0.1)]), ]); let err_fn = |err| eprintln!("an error occurred on stream: {}", err); let stream = device.build_output_stream( config, move |data: &mut [T], _: &cpal::OutputCallbackInfo| { let blocks_needed = data.len() / 2 / BLOCK_SIZE; let block_step = channels * BLOCK_SIZE; for current_block in 0..blocks_needed { let block = ctx.next_block(); for i in 0..BLOCK_SIZE { for chan in 0..channels { let value: T = T::from_sample(block[chan][i]); data[(i * channels + chan) + (current_block) * block_step] = value; } } } }, err_fn, None, )?; stream.play()?; std::thread::sleep(std::time::Duration::from_millis(3000)); Ok(()) }