1use jack_sys as j;
2use std::mem;
3use std::sync::atomic::{AtomicBool, Ordering};
4
5pub struct RingBuffer(*mut j::jack_ringbuffer_t);
24
25impl RingBuffer {
26 pub fn new(size: usize) -> Result<Self, crate::Error> {
28 let insize = size as libc::size_t;
29 let handle = unsafe { j::jack_ringbuffer_create(insize) };
30
31 if handle.is_null() {
32 return Err(crate::Error::RingbufferCreateFailed);
33 }
34
35 Ok(RingBuffer(handle))
36 }
37
38 pub fn mlock(&mut self) {
40 unsafe { j::jack_ringbuffer_mlock(self.0) };
41 }
42
43 pub fn reset(&mut self) {
45 unsafe { j::jack_ringbuffer_reset(self.0) };
46 }
47
48 pub fn into_reader_writer(self) -> (RingBufferReader, RingBufferWriter) {
50 let out = unsafe { (RingBufferReader::new(self.0), RingBufferWriter::new(self.0)) };
51 mem::forget(self);
52 out
53 }
54
55 pub fn from_reader_writer(r: RingBufferReader, w: RingBufferWriter) -> Self {
62 if r.ringbuffer_handle != w.ringbuffer_handle {
63 panic!("mismatching read and write handles!")
66 }
67
68 let handle = RingBuffer(r.ringbuffer_handle);
71 mem::forget(r);
72 mem::forget(w);
73
74 handle
75 }
76}
77
78impl Drop for RingBuffer {
79 fn drop(&mut self) {
80 if !self.0.is_null() {
81 unsafe { j::jack_ringbuffer_free(self.0) };
82 }
83 self.0 = std::ptr::null_mut();
84 }
85}
86
87unsafe impl Send for RingBuffer {}
88unsafe impl Sync for RingBuffer {}
89
90pub struct RingBufferReader {
93 ringbuffer_handle: *mut j::jack_ringbuffer_t,
94 both_live: AtomicBool,
97}
98
99unsafe impl Send for RingBufferReader {}
100unsafe impl Sync for RingBufferReader {}
101
102pub struct RingBufferWriter {
105 ringbuffer_handle: *mut j::jack_ringbuffer_t,
106 both_live: AtomicBool,
107}
108
109unsafe impl Send for RingBufferWriter {}
110unsafe impl Sync for RingBufferWriter {}
111
112impl RingBufferReader {
113 unsafe fn new(raw: *mut j::jack_ringbuffer_t) -> Self {
116 RingBufferReader {
117 ringbuffer_handle: raw,
118 both_live: AtomicBool::new(true),
119 }
120 }
121
122 pub fn get_vector(&self) -> (&[u8], &[u8]) {
128 let mut vec = [
129 j::jack_ringbuffer_data_t::default(),
130 j::jack_ringbuffer_data_t::default(),
131 ];
132 let vecstart = &mut vec[0] as *mut j::jack_ringbuffer_data_t;
133
134 unsafe { j::jack_ringbuffer_get_read_vector(self.ringbuffer_handle, vecstart) };
135
136 let view1 = vec[0];
137 let view2 = vec[1];
138
139 let buf1 = view1.buf as *mut u8;
140 let len1 = view1.len;
141
142 let mut buf2 = view2.buf as *mut u8;
143 let len2 = view2.len;
144
145 if len2 == 0 {
146 buf2 = buf1;
148 }
149
150 let view1 = unsafe { std::slice::from_raw_parts(buf1, len1) };
151 let view2 = unsafe { std::slice::from_raw_parts(buf2, len2) };
152 (view1, view2)
153 }
154
155 pub fn read_buffer(&mut self, buf: &mut [u8]) -> usize {
158 if buf.is_empty() {
159 return 0;
160 }
161
162 let insize: libc::size_t = buf.len() as libc::size_t;
163 let bufstart = &mut buf[0] as *mut _ as *mut libc::c_char;
164
165 unsafe { j::jack_ringbuffer_read(self.ringbuffer_handle, bufstart, insize) }
166 }
167
168 pub fn read_slice<'a>(&mut self, buf: &'a mut [u8]) -> &'a [u8] {
170 let len = self.read_buffer(buf);
171 &buf[0..len]
172 }
173
174 pub fn peek(&self, buf: &mut [u8]) -> usize {
180 if buf.is_empty() {
181 return 0;
182 }
183
184 let insize: libc::size_t = buf.len() as libc::size_t;
185 let bufstart = &mut buf[0] as *mut _ as *mut libc::c_char;
186
187 unsafe { j::jack_ringbuffer_peek(self.ringbuffer_handle, bufstart, insize) }
188 }
189
190 pub fn advance(&mut self, cnt: usize) {
193 let incnt = cnt as libc::size_t;
194 unsafe { j::jack_ringbuffer_read_advance(self.ringbuffer_handle, incnt) };
195 }
196
197 pub fn space(&self) -> usize {
199 unsafe { j::jack_ringbuffer_read_space(self.ringbuffer_handle) }
200 }
201
202 pub fn peek_iter(
204 &'_ self,
205 ) -> std::iter::Chain<std::slice::Iter<'_, u8>, std::slice::Iter<'_, u8>> {
206 let (view1, view2) = self.get_vector();
207
208 view1.iter().chain(view2.iter())
209 }
210}
211
212impl std::io::Read for RingBufferReader {
213 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
214 Ok(self.read_buffer(buf))
215 }
216}
217
218impl Drop for RingBufferReader {
219 fn drop(&mut self) {
220 match self
221 .both_live
222 .compare_exchange(true, false, Ordering::SeqCst, Ordering::SeqCst)
223 {
224 Ok(false) | Err(false) => {
225 drop(RingBuffer(self.ringbuffer_handle));
226 }
227 _ => (),
228 }
229 }
230}
231
232impl RingBufferWriter {
233 unsafe fn new(raw: *mut j::jack_ringbuffer_t) -> Self {
236 RingBufferWriter {
237 ringbuffer_handle: raw,
238 both_live: AtomicBool::new(true),
239 }
240 }
241
242 pub fn write_buffer(&mut self, buf: &[u8]) -> usize {
245 if buf.is_empty() {
246 return 0;
247 }
248
249 let insize: libc::size_t = buf.len() as libc::size_t;
250 let bufstart = &buf[0] as *const _ as *const libc::c_char;
251
252 unsafe { j::jack_ringbuffer_write(self.ringbuffer_handle, bufstart, insize) }
253 }
254
255 pub fn advance(&mut self, cnt: usize) {
258 let incnt = cnt as libc::size_t;
259 unsafe { j::jack_ringbuffer_write_advance(self.ringbuffer_handle, incnt) };
260 }
261
262 pub fn space(&mut self) -> usize {
264 unsafe { j::jack_ringbuffer_write_space(self.ringbuffer_handle) }
265 }
266
267 pub fn get_vector(&mut self) -> (&mut [u8], &mut [u8]) {
271 let mut vec = [
272 j::jack_ringbuffer_data_t::default(),
273 j::jack_ringbuffer_data_t::default(),
274 ];
275 let vecstart = &mut vec[0] as *mut j::jack_ringbuffer_data_t;
276
277 unsafe { j::jack_ringbuffer_get_write_vector(self.ringbuffer_handle, vecstart) };
278
279 let view1 = vec[0];
280 let view2 = vec[1];
281
282 let buf1 = view1.buf as *mut u8;
283 let len1 = view1.len;
284
285 let mut buf2 = view2.buf as *mut u8;
286 let len2 = view2.len;
287
288 if len2 == 0 {
289 buf2 = buf1;
291 }
292
293 let view1 = unsafe { std::slice::from_raw_parts_mut(buf1, len1) };
294 let view2 = unsafe { std::slice::from_raw_parts_mut(buf2, len2) };
295 (view1, view2)
296 }
297
298 pub fn peek_iter(
300 &'_ mut self,
301 ) -> std::iter::Chain<std::slice::IterMut<'_, u8>, std::slice::IterMut<'_, u8>> {
302 let (view1, view2) = self.get_vector();
303
304 view1.iter_mut().chain(view2.iter_mut())
305 }
306}
307
308impl std::io::Write for RingBufferWriter {
309 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
310 Ok(self.write_buffer(buf))
311 }
312
313 fn flush(&mut self) -> std::io::Result<()> {
314 Ok(())
315 }
316}
317
318impl Drop for RingBufferWriter {
319 fn drop(&mut self) {
320 match self
321 .both_live
322 .compare_exchange(true, false, Ordering::SeqCst, Ordering::SeqCst)
323 {
324 Ok(false) | Err(false) => {
325 drop(RingBuffer(self.ringbuffer_handle));
326 }
327 _ => (),
328 }
329 }
330}