1 use std::ops::{Deref, DerefMut};
2 use std::slice;
3 
4 use jack_sys as j;
5 use libc;
6 
7 use client::ProcessScope;
8 use port::{Port, PortSpec};
9 use port::port_flags::{IS_INPUT, IS_OUTPUT, PortFlags};
10 
11 /// `AudioInSpec` implements the `PortSpec` trait which, defines an
12 /// endpoint for JACK. In this case, it is a readable 32 bit floating
13 /// point buffer for audio.
14 ///
15 /// `AudioInSpec::buffer()` is used to gain access the buffer.
16 ///
17 /// # Example
18 /// ```
19 /// let client = jack::client::Client::new("rusty_client",
20 /// jack::client::client_options::NO_START_SERVER).unwrap().0;
21 /// let spec = jack::port::AudioInSpec::default();
22 /// let audio_in_port = client.register_port("in", spec).unwrap();
23 /// ```
24 #[derive(Debug, Default)]
25 pub struct AudioInSpec;
26 
27 /// `AudioOutSpec` implements the `PortSpec` trait, which defines an
28 /// endpoint for JACK. In this case, it is a mutable 32 bit floating
29 /// point buffer for audio.
30 ///
31 /// `AudioOutSpec::buffer()` is used to gain access the buffer.
32 ///
33 /// # Example
34 /// ```
35 /// let client = jack::client::Client::new("rusty_client",
36 /// jack::client::client_options::NO_START_SERVER).unwrap().0;
37 /// let spec = jack::port::AudioInSpec::default();
38 /// let audio_out_port = client.register_port("out", spec).unwrap();
39 /// ```
40 #[derive(Debug, Default)]
41 pub struct AudioOutSpec;
42 
43 
44 unsafe impl<'a> PortSpec for AudioOutSpec {
jack_port_type(&self) -> &'static str45     fn jack_port_type(&self) -> &'static str {
46         j::FLOAT_MONO_AUDIO
47     }
48 
jack_flags(&self) -> PortFlags49     fn jack_flags(&self) -> PortFlags {
50         IS_OUTPUT
51     }
52 
jack_buffer_size(&self) -> libc::c_ulong53     fn jack_buffer_size(&self) -> libc::c_ulong {
54         // Not needed for built in types according to JACK api
55         0
56     }
57 }
58 
59 unsafe impl PortSpec for AudioInSpec {
60     /// Create an AudioInSpec instance from a buffer pointer and frame
61     /// count. This is mostly used by `Port<AudioInSpec>` within a
62     /// `process` scope.
63     ///
64     /// # Arguments
65     ///
66     /// * `ptr` - buffer pointer to underlying data.
67     ///
68     /// * `nframes` - the size of the buffer.
69 
jack_port_type(&self) -> &'static str70     fn jack_port_type(&self) -> &'static str {
71         j::FLOAT_MONO_AUDIO
72     }
73 
jack_flags(&self) -> PortFlags74     fn jack_flags(&self) -> PortFlags {
75         IS_INPUT
76     }
77 
jack_buffer_size(&self) -> libc::c_ulong78     fn jack_buffer_size(&self) -> libc::c_ulong {
79         // Not needed for built in types according to JACK api
80         0
81     }
82 }
83 
84 /// Safely and thinly wrap a `Port<AudioOutSpec>`. Derefs into a `&mut[f32]`.
85 ///
86 /// # Example
87 /// ```
88 /// let client = jack::client::Client::new("c",
89 /// jack::client::client_options::NO_START_SERVER).unwrap().0;
90 /// let mut out_port = client.register_port("p",
91 /// jack::port::AudioOutSpec::default()).unwrap();
92 /// let _process = move |_: &jack::client::Client, ps:
93 /// &jack::client::ProcessScope| {
94 ///     let mut out_p = jack::port::AudioOutPort::new(&mut out_port, ps);
95 ///     {
96 ///         let out_b: &mut [f32] = &mut out_p; // can deref into &mut [f32]
97 ///     }
98 ///     out_p[0] = 0.0;
99 /// };
100 /// ```
101 pub struct AudioOutPort<'a> {
102     _port: &'a mut Port<AudioOutSpec>,
103     buffer: &'a mut [f32],
104 }
105 
106 impl<'a> AudioOutPort<'a> {
107     /// Wrap a `Port<AudioOutSpec>` within a process scope of a client
108     /// that registered the port. Panics if the port does not belong
109     /// to the client that created the process.
new(port: &'a mut Port<AudioOutSpec>, ps: &'a ProcessScope) -> Self110     pub fn new(port: &'a mut Port<AudioOutSpec>, ps: &'a ProcessScope) -> Self {
111         assert_eq!(port.client_ptr(), ps.client_ptr());
112         let buff = unsafe {
113             slice::from_raw_parts_mut(
114                 port.buffer(ps.n_frames()) as *mut f32,
115                 ps.n_frames() as usize,
116             )
117         };
118         AudioOutPort {
119             _port: port,
120             buffer: buff,
121         }
122     }
123 }
124 
125 impl<'a> Deref for AudioOutPort<'a> {
126     type Target = [f32];
127 
deref(&self) -> &[f32]128     fn deref(&self) -> &[f32] {
129         self.buffer
130     }
131 }
132 
133 impl<'a> DerefMut for AudioOutPort<'a> {
deref_mut(&mut self) -> &mut [f32]134     fn deref_mut(&mut self) -> &mut [f32] {
135         self.buffer
136     }
137 }
138 
139 
140 /// Safely and thinly wrap a `Port<AudioInSpec>`. Derefs into a `&[f32]`.
141 ///
142 /// # Example
143 /// ```
144 /// let client = jack::client::Client::new("c",
145 /// jack::client::client_options::NO_START_SERVER).unwrap().0;
146 /// let in_port = client.register_port("p",
147 /// jack::port::AudioInSpec::default()).unwrap();
148 /// let process = move |_: &jack::client::Client, ps:
149 /// &jack::client::ProcessScope| {
150 ///     let in_p = jack::port::AudioInPort::new(&in_port, ps);
151 ///     {
152 ///         let _in_b: &[f32] = &in_p; // can deref into &[f32]
153 ///     }
154 ///     let _x = in_p[0];
155 /// };
156 /// ```
157 pub struct AudioInPort<'a> {
158     _port: &'a Port<AudioInSpec>,
159     buffer: &'a [f32],
160 }
161 
162 impl<'a> AudioInPort<'a> {
163     /// Wrap a `Port<AudioInSpec>` within a process scope of a client
164     /// that registered the port. Panics if the port does not belong
165     /// to the client that created the process.
new(port: &'a Port<AudioInSpec>, ps: &'a ProcessScope) -> Self166     pub fn new(port: &'a Port<AudioInSpec>, ps: &'a ProcessScope) -> Self {
167         assert_eq!(port.client_ptr(), ps.client_ptr());
168         let buff = unsafe {
169             slice::from_raw_parts(
170                 port.buffer(ps.n_frames()) as *const f32,
171                 ps.n_frames() as usize,
172             )
173         };
174         AudioInPort {
175             _port: port,
176             buffer: buff,
177         }
178     }
179 }
180 
181 impl<'a> Deref for AudioInPort<'a> {
182     type Target = [f32];
183 
deref(&self) -> &[f32]184     fn deref(&self) -> &[f32] {
185         self.buffer
186     }
187 }
188