simple_client/
simple_client.rs1extern crate easyjack as jack;
3
4extern crate nix;
10
11use nix::sys::signal;
12use std::sync::atomic;
13use std::sync::mpsc::{SyncSender, Receiver};
14use std::sync::mpsc;
15use std::thread;
16use std::time::Duration;
17
18const N: usize = 200;
20
21static RUNNING: atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT;
24
25struct AudioHandler {
32 samples: [jack::DefaultAudioSample; N],
34
35 right_phase: usize,
37 left_phase: usize,
38
39 right_output: jack::OutputPortHandle<jack::DefaultAudioSample>,
42 left_output: jack::OutputPortHandle<jack::DefaultAudioSample>,
43
44 incoming: Receiver<[jack::DefaultAudioSample; N]>,
48}
49
50impl AudioHandler {
51 fn new(
53 init_samples: [jack::DefaultAudioSample; N],
54 right: jack::OutputPortHandle<jack::DefaultAudioSample>,
55 left: jack::OutputPortHandle<jack::DefaultAudioSample>,
56 incoming: Receiver<[jack::DefaultAudioSample; N]>) -> Self
57 {
58 AudioHandler {
59 samples: init_samples,
60 right_phase: 0,
61 left_phase: 0,
62 right_output: right,
63 left_output: left,
64 incoming: incoming
65 }
66 }
67}
68
69impl jack::ProcessHandler for AudioHandler {
71 fn process(&mut self, ctx: &jack::CallbackContext, nframes: jack::NumFrames) -> i32 {
72 let right = self.right_output.get_write_buffer(nframes, ctx);
74 let left = self.left_output.get_write_buffer(nframes, ctx);
75
76 for i in 0..(nframes as usize) {
78 right[i] = self.samples[self.right_phase];
79 left[i] = self.samples[self.left_phase];
80
81 self.right_phase = self.right_phase + 1;
83 self.left_phase = self.left_phase + 3;
84
85 if self.right_phase >= self.samples.len() {
86 self.right_phase = 0
87 }
88
89 if self.left_phase >= self.samples.len() {
90 self.left_phase = 0
91 }
92 }
93
94 match self.incoming.try_recv() {
96 Ok(samples) => self.samples = samples,
97 Err(_) => (),
98 };
99
100 0
101 }
102}
103
104struct SimpleClient<'a> {
107 client: jack::Client<'a>,
108 sender: SyncSender<[jack::DefaultAudioSample; N]>,
109}
110
111impl<'a> SimpleClient<'a> {
112 fn new() -> Result<Self, jack::status::Status> {
113 let client = jack::Client::open("simple", jack::options::NO_START_SERVER);
114 let mut client = match client {
115 Ok((client, _)) => client,
116 Err(code) => return Err(code),
117 };
118
119 let right = client.register_output_audio_port("output1").unwrap();
121 let left = client.register_output_audio_port("output2").unwrap();
122
123 let (tx, rx) = mpsc::sync_channel(1);
125
126 let handler = AudioHandler::new(SimpleClient::compute_sine(0.2), right, left, rx);
128 client.set_process_handler(handler).unwrap();
129
130 Ok(SimpleClient {
131 client: client,
132 sender: tx,
133 })
134 }
135
136 fn activate(&mut self) -> Result<(), jack::status::Status> {
137 self.client.activate()
138 }
139
140 fn run(mut self) {
141 let mut i = 0;
142 while RUNNING.load(atomic::Ordering::SeqCst) {
143 let newsine = SimpleClient::compute_sine(i as f32 / 10.0);
144
145 match self.sender.send(newsine) {
146 Ok(_) => (),
147 Err(_) => (),
148 };
149
150 i += 1;
151 if i > 10 {
152 i = 0
153 }
154
155 thread::sleep(Duration::from_millis(1000));
156 }
157
158 println!("tearing down");
159 self.client.close().unwrap();
160 }
161
162 fn compute_sine(constant: f32) -> [jack::DefaultAudioSample; N] {
163 let mut sine = [0.0; N];
164 for i in 0..N {
165 let inner = ((i as f32) / (N as f32)) * 3.14159265 * 2.0;
166 sine[i] = constant * inner.sin();
167 }
168
169 sine
170 }
171}
172
173extern "C" fn handle_sigint(_: i32) {
174 RUNNING.store(false, atomic::Ordering::SeqCst);
175}
176
177fn main() {
178 let action = signal::SigAction::new(
180 signal::SigHandler::Handler(handle_sigint),
181 signal::SaFlags::empty(),
182 signal::SigSet::empty());
183
184 unsafe { signal::sigaction(signal::Signal::SIGINT, &action) }.unwrap();
185
186 RUNNING.store(true, atomic::Ordering::SeqCst);
188
189 let mut c = SimpleClient::new().unwrap();
190 c.activate().unwrap();
191 c.run()
192}