use crossbeam_channel::bounded;
use std::io;
use std::str::FromStr;
fn main() {
let (client, _status) =
jack::Client::new("rust_jack_sine", jack::ClientOptions::default()).unwrap();
let out_port = client
.register_port("sine_out", jack::AudioOut::default())
.unwrap();
let (tx, rx) = bounded(1_000_000);
struct State {
out_port: jack::Port<jack::AudioOut>,
rx: crossbeam_channel::Receiver<f64>,
frequency: f64,
frame_t: f64,
time: f64,
}
let process = jack::contrib::ClosureProcessHandler::with_state(
State {
out_port,
rx,
frequency: 220.0,
frame_t: 1.0 / client.sample_rate() as f64,
time: 0.0,
},
|state, _, ps| -> jack::Control {
let out = state.out_port.as_mut_slice(ps);
while let Ok(f) = state.rx.try_recv() {
state.time = 0.0;
state.frequency = f;
}
for v in out.iter_mut() {
let x = state.frequency * state.time * 2.0 * std::f64::consts::PI;
let y = x.sin();
*v = y as f32;
state.time += state.frame_t;
}
jack::Control::Continue
},
move |_, _, _| jack::Control::Continue,
);
let active_client = client.activate_async((), process).unwrap();
active_client
.as_client()
.connect_ports_by_name("rust_jack_sine:sine_out", "system:playback_1")
.unwrap();
active_client
.as_client()
.connect_ports_by_name("rust_jack_sine:sine_out", "system:playback_2")
.unwrap();
println!("Enter an integer value to change the frequency of the sine wave.");
while let Some(f) = read_freq() {
tx.send(f).unwrap();
}
if let Err(err) = active_client.deactivate() {
eprintln!("JACK exited with error: {err}");
};
}
fn read_freq() -> Option<f64> {
let mut user_input = String::new();
match io::stdin().read_line(&mut user_input) {
Ok(_) => u16::from_str(user_input.trim()).ok().map(|n| n as f64),
Err(_) => None,
}
}