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