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