//! Implement the media player example from the Python tutorial, but in Rust. use std::io::Write; use std::str::FromStr; use synthizer as syz; fn help() { print!( r#"Commands: pause, play: pause and/or play the media. pos x y z: move the source to the position x y z. seek pos: seek to position pos in seconds. gain value: control the gain of the generator in db quit: exit. "# ); } fn main_impl(input_file: &str) -> syz::Result<()> { let mut init_cfg = syz::LibraryConfig::new(); init_cfg.log_to_stderr(); init_cfg.log_level(syz::LogLevel::Debug); let _guard = init_cfg.initialize()?; let ctx = syz::Context::new()?; ctx.default_panner_strategy() .set(syz::PannerStrategy::Hrtf)?; let src = syz::Source3D::new(&ctx, syz::PannerStrategy::Delegate, (0.0, 0.0, 0.0))?; let gen = syz::BufferGenerator::new(&ctx)?; let syz_buf = syz::Buffer::from_file(input_file)?; gen.buffer().set(&syz_buf)?; src.add_generator(&gen)?; let mut looping = false; let stdin = std::io::stdin(); let mut stdout = std::io::stdout(); loop { print!("> "); stdout.flush().expect("Should flush"); let mut line = String::new(); stdin.read_line(&mut line).expect("Should always read"); let line = line.trim(); if line == "quit" { break; } let parts = line.split_whitespace().collect::>(); if parts.is_empty() { continue; } match parts[0] { "help" => { help(); } "pause" => { src.pause()?; } "play" => { src.play()?; } "loop" => { looping = !looping; gen.looping().set(looping)?; } "seek" => { if parts.len() != 2 { println!("Usage: seek "); } let pos = match f64::from_str(parts[1]) { Ok(f) => f, Err(_) => { println!("Invalid position"); continue; } }; gen.playback_position().set(pos)?; } "pos" => { if parts.len() != 4 { println!("Usage: pos x y z"); continue; } let m_x = f64::from_str(parts[1]); let m_y = f64::from_str(parts[2]); let m_z = f64::from_str(parts[3]); let pos = match (m_x, m_y, m_z) { (Ok(x), Ok(y), Ok(z)) => (x, y, z), _ => { println!("Unable to parse position"); continue; } }; src.position().set(pos)?; } "gain" => { if parts.len() != 2 { println!("Usage: gain "); continue; } let gain_db = match f64::from_str(parts[1]) { Ok(g) => g, Err(_) => { println!("Unable to parse gain"); continue; } }; let gain = 10.0f64.powf(gain_db / 20.0); src.gain().set(gain)?; } _ => { println!("Invalid command. Type help for usage"); } } } Ok(()) } fn main() -> std::result::Result<(), &'static str> { let args = std::env::args().collect::>(); if args.len() != 2 { println!("Usage: {} ", args[0]); return Err("Failed"); } main_impl(args[1].as_str()).expect("Should succeed"); Ok(()) }