use std::collections::VecDeque; use std::fs::File; use std::io::Read; use std::net::*; use std::sync::*; use std::{env, ffi, iter, thread}; use cpal::traits::{HostTrait, DeviceTrait, StreamTrait}; use synfone::client::*; use synfone::lang::*; use synfone::proto::*; use synfone::synth::*; use synfone::*; fn main() -> Result<(), std::io::Error> { let cmd = env::args_os().nth(1).expect("Please pass a command as the first argument; use `help` as a command for more information."); let cmds = cmd.into_string().expect("Couldn't parse command"); let new_args: Vec = env::args_os().skip(1).collect(); match &*cmds { "help" => eprintln!("TODO! Commands are help, client."), "client" => main_client(new_args)?, _ => eprintln!("Unknown command; `help` for help."), } Ok(()) } fn main_client(args: Vec) -> Result<(), std::io::Error> { let host = cpal::default_host(); let device = host.default_output_device().expect("no default host audio device!"); let mut conf_range = device.supported_output_configs().expect("could not query audio device capabilities -- audio device disconnected?"); let conf = conf_range.next().expect("audio device has no supported configs!").with_max_sample_rate().config(); println!("playing at sample rate {}", conf.sample_rate.0); let env = Environment { sample_rate: conf.sample_rate.0 as f32, default_buffer_size: 64, }; let mut genfile = File::open( args.iter() .nth(1) .expect("Need first argument to be a file with a generator vector"), ) .expect("Failed to open file"); let mut genstr = String::new(); genfile.read_to_string(&mut genstr)?; let gens = Parser::new(Tokenizer::new(genstr.chars()), env.clone()) .expect("Failed to get first token") .parse_gen_vec() .expect("Failed to compile generators"); let sock = UdpSocket::bind("0.0.0.0:13676").expect("Failed to bind socket"); eprintln!("Parsed {} generator definitions", gens.len()); let client = Arc::new(Mutex::new( Client::new( sock.try_clone().expect("Failed to clone socket"), gens, env.clone(), ) .expect("Failed to create client"), )); let last_buffer = Arc::new(Mutex::new(>::with_capacity( env.default_buffer_size * 9, ))); let last_buffer_lim = env.default_buffer_size * 8; last_buffer .lock() .expect("Failed to init shared buffer") .append(&mut iter::repeat(0.0f32).take(last_buffer_lim).collect()); let stream; { let client = client.clone(); let last_buffer = last_buffer.clone(); let mut ring: VecDeque = VecDeque::new(); ring.reserve_exact(2 * env.default_buffer_size); stream = device.build_output_stream( &conf, move |data: &mut [f32], _: &cpal::OutputCallbackInfo| { let frames = data.len(); while frames > ring.len() { let mut cli = client.lock().unwrap(); cli.next_frames(); { let mut buf = last_buffer .lock() .expect("Failed to acquire shared buffer in audio callback"); buf.append(&mut cli.buffer().samples.iter().map(|&x| x).collect()); let len = buf.len(); if len > last_buffer_lim { buf.drain(..(len - last_buffer_lim)); } } ring.append(&mut cli.buffer().iter().map(|&x| x).collect()); } let mut drain = ring.drain(..frames); let mut min = 1.0; let mut max = 0.0; for i in 0..frames { let frame = drain.next().unwrap(); min = f32::min(min, frame); max = f32::max(min, frame); data[i] = frame; } println!("played {} frames, min {}, max {}", frames, min, max); }, move |err| { println!("audio stream error: {}", err); } ).expect("could not create audio stream!"); } eprintln!("Starting."); stream.play().expect("Failed to start stream"); eprintln!("Audio stream started."); let net_thread = { let client = client.clone(); let net_thread = thread::spawn(move || { let mut buffer: [u8; Command::SIZE] = [0u8; Command::SIZE]; loop { let (bytes, sender) = sock.recv_from(&mut buffer).unwrap(); if bytes < Command::SIZE { continue; } let cmd = Command::from(&buffer); { let mut cli = client.lock().unwrap(); if !cli.handle_command(cmd, sender) { break; } } } }); net_thread }; eprintln!("Network thread started."); net_thread.join().expect("Network thread panicked"); eprintln!("Exiting."); Ok(()) }