use warbler::{ChirpParams, Synthesizer};
fn print_usage() {
eprintln!("usage: warbler [preset]");
eprintln!();
eprintln!("presets:");
eprintln!(" sparrow - sharp, quick chirp (2.5-5kHz, 150ms)");
eprintln!(" robin - melodic warble with vibrato (2-3.5kHz, 300ms)");
eprintln!(" warbler - complex trill (3-6kHz, 180ms)");
eprintln!(" finch - high-pitched tweet (3.5-7kHz, 120ms)");
eprintln!(" default - basic chirp");
eprintln!();
eprintln!("or use flags for custom chirp:");
eprintln!(" --start-freq <hz> starting frequency");
eprintln!(" --end-freq <hz> ending frequency");
eprintln!(" --duration <ms> duration in milliseconds");
eprintln!(" --volume <0.0-1.0> volume");
}
fn parse_custom_params(args: &[String]) -> Result<ChirpParams, String> {
let mut params = ChirpParams::new();
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--start-freq" => {
i += 1;
if i >= args.len() {
return Err("--start-freq requires value".to_string());
}
params.start_freq_hz = args[i]
.parse()
.map_err(|_| "invalid start-freq".to_string())?;
}
"--end-freq" => {
i += 1;
if i >= args.len() {
return Err("--end-freq requires value".to_string());
}
params.end_freq_hz = args[i]
.parse()
.map_err(|_| "invalid end-freq".to_string())?;
}
"--duration" => {
i += 1;
if i >= args.len() {
return Err("--duration requires value".to_string());
}
params.duration_ms = args[i]
.parse()
.map_err(|_| "invalid duration".to_string())?;
}
"--volume" => {
i += 1;
if i >= args.len() {
return Err("--volume requires value".to_string());
}
let vol: f32 = args[i]
.parse()
.map_err(|_| "invalid volume".to_string())?;
params.volume = vol.clamp(0.0, 1.0);
}
arg => return Err(format!("unknown flag: {}", arg)),
}
i += 1;
}
Ok(params)
}
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() < 2 {
eprintln!("playing default chirp...");
let synth = Synthesizer::new().unwrap_or_else(|e| {
eprintln!("failed to initialize audio: {}", e);
std::process::exit(1);
});
if let Err(e) = synth.play_chirp(ChirpParams::new()) {
eprintln!("error playing chirp: {}", e);
std::process::exit(1);
}
return;
}
let preset = &args[1];
if preset == "--help" || preset == "-h" {
print_usage();
return;
}
let params = if preset.starts_with("--") {
match parse_custom_params(&args) {
Ok(p) => {
eprintln!(
"playing custom chirp: {:.0}Hz -> {:.0}Hz over {}ms",
p.start_freq_hz, p.end_freq_hz, p.duration_ms
);
p
}
Err(e) => {
eprintln!("error: {}", e);
print_usage();
std::process::exit(1);
}
}
} else {
let p = match preset.as_str() {
"sparrow" => {
eprintln!("chirping like a sparrow...");
warbler::sparrow()
}
"robin" => {
eprintln!("warbling like a robin...");
warbler::robin()
}
"warbler" => {
eprintln!("trilling like a warbler...");
warbler::warbler()
}
"finch" => {
eprintln!("tweeting like a finch...");
warbler::finch()
}
"default" => {
eprintln!("playing default chirp...");
ChirpParams::new()
}
_ => {
eprintln!("unknown preset: {}", preset);
print_usage();
std::process::exit(1);
}
};
p
};
let synth = Synthesizer::new().unwrap_or_else(|e| {
eprintln!("failed to initialize audio: {}", e);
std::process::exit(1);
});
if let Err(e) = synth.play_chirp(params) {
eprintln!("error playing chirp: {}", e);
std::process::exit(1);
}
}