1 //! Sine wave generator with frequency configuration exposed through standard
2 //! input.
3 extern crate jack;
4 use jack::prelude::{AsyncClient, AudioOutPort, AudioOutSpec, Client, ClosureProcessHandler,
5 JackControl, ProcessScope, client_options};
6 use std::io;
7 use std::str::FromStr;
8 use std::sync::mpsc::channel;
9
10
11 /// Attempt to read a frequency from standard in. Will block until there is
12 /// user input. `None` is
13 /// returned if there was an error reading from standard in, or the retrieved
14 /// string wasn't a
15 /// compatible u16 integer.
read_freq() -> Option<f64>16 fn read_freq() -> Option<f64> {
17 let mut user_input = String::new();
18 match io::stdin().read_line(&mut user_input) {
19 Ok(_) => u16::from_str(&user_input.trim()).ok().map(|n| n as f64),
20 Err(_) => None,
21 }
22 }
23
main()24 fn main() {
25 // 1. open a client
26 let (client, _status) = Client::new("rust_jack_sine", client_options::NO_START_SERVER).unwrap();
27
28 // 2. register port
29 let mut out_port = client
30 .register_port("sine_out", AudioOutSpec::default())
31 .unwrap();
32
33 // 3. define process callback handler
34 let mut frequency = 220.0;
35 let sample_rate = client.sample_rate();
36 let frame_t = 1.0 / sample_rate as f64;
37 let mut time = 0.0;
38 let (tx, rx) = channel();
39 let process = ClosureProcessHandler::new(move |_: &Client, ps: &ProcessScope| -> JackControl {
40 // Get output buffer
41 let mut out_p = AudioOutPort::new(&mut out_port, ps);
42 let out: &mut [f32] = &mut out_p;
43
44 // Check frequency requests
45 while let Ok(f) = rx.try_recv() {
46 time = 0.0;
47 frequency = f;
48 }
49
50 // Write output
51 for v in out.iter_mut() {
52 let x = frequency * time * 2.0 * std::f64::consts::PI;
53 let y = x.sin();
54 *v = y as f32;
55 time += frame_t;
56 }
57
58 // Continue as normal
59 JackControl::Continue
60 });
61
62 // 4. activate the client
63 let active_client = AsyncClient::new(client, (), process).unwrap();
64 // processing starts here
65
66 // 5. wait or do some processing while your handler is running in real time.
67 println!("Enter an integer value to change the frequency of the sine wave.");
68 while let Some(f) = read_freq() {
69 tx.send(f).unwrap();
70 }
71
72 // 6. Optional deactivate. Not required since active_client will deactivate on
73 // drop, though
74 // explicit deactivate may help you identify errors in deactivate.
75 active_client.deactivate().unwrap();
76 }
77