clack_plugin/process/audio/
output.rs1use crate::internal_utils::{slice_from_external_parts, slice_from_external_parts_mut};
2use crate::prelude::Audio;
3use crate::process::InputChannelsIter;
4use crate::process::audio::{BufferError, SampleType};
5use clack_common::process::ConstantMask;
6use clap_sys::audio_buffer::clap_audio_buffer;
7use std::slice::IterMut;
8
9pub struct OutputPortsIter<'a> {
11 outputs: IterMut<'a, clap_audio_buffer>,
12 frames_count: u32,
13}
14
15impl<'a> OutputPortsIter<'a> {
16 #[inline]
17 pub(crate) fn new(audio: &'a mut Audio<'_>) -> Self {
18 Self {
19 outputs: audio.outputs.iter_mut(),
20 frames_count: audio.frames_count,
21 }
22 }
23}
24
25impl<'a> Iterator for OutputPortsIter<'a> {
26 type Item = OutputPort<'a>;
27
28 #[inline]
29 fn next(&mut self) -> Option<Self::Item> {
30 self.outputs
31 .next()
32 .map(|buf| unsafe { OutputPort::from_raw(buf, self.frames_count) })
35 }
36
37 #[inline]
38 fn size_hint(&self) -> (usize, Option<usize>) {
39 self.outputs.size_hint()
40 }
41}
42
43impl ExactSizeIterator for OutputPortsIter<'_> {
44 #[inline]
45 fn len(&self) -> usize {
46 self.outputs.len()
47 }
48}
49
50pub struct OutputPort<'a> {
52 inner: &'a mut clap_audio_buffer,
53 frames_count: u32,
54}
55
56impl<'a> OutputPort<'a> {
57 #[inline]
62 pub(crate) unsafe fn from_raw(inner: &'a mut clap_audio_buffer, frames_count: u32) -> Self {
63 Self {
64 inner,
65 frames_count,
66 }
67 }
68
69 #[inline]
101 pub fn channels(
102 &mut self,
103 ) -> Result<SampleType<OutputChannels<'a, f32>, OutputChannels<'a, f64>>, BufferError> {
104 Ok(unsafe { SampleType::from_raw_buffer_mut(self.inner) }?.map(
106 |data| OutputChannels {
107 data,
108 frames_count: self.frames_count,
109 },
110 |data| OutputChannels {
111 data,
112 frames_count: self.frames_count,
113 },
114 ))
115 }
116
117 #[inline]
121 pub fn frames_count(&self) -> u32 {
122 self.frames_count
123 }
124
125 #[inline]
127 pub fn channel_count(&self) -> u32 {
128 self.inner.channel_count
129 }
130
131 #[inline]
133 pub fn latency(&self) -> u32 {
134 self.inner.latency
135 }
136
137 #[inline]
139 pub fn constant_mask(&self) -> ConstantMask {
140 ConstantMask::from_bits(self.inner.constant_mask)
141 }
142
143 #[inline]
145 pub fn set_constant_mask(&mut self, new_mask: ConstantMask) {
146 self.inner.constant_mask = new_mask.to_bits()
147 }
148}
149
150pub struct OutputChannels<'a, S> {
155 pub(crate) frames_count: u32,
156 pub(crate) data: &'a mut [*mut S],
157}
158
159impl<S> OutputChannels<'_, S> {
160 #[inline]
164 pub fn frames_count(&self) -> u32 {
165 self.frames_count
166 }
167
168 #[inline]
173 pub fn raw_data(&self) -> &[*mut S] {
174 self.data
175 }
176
177 #[inline]
179 pub fn channel_count(&self) -> u32 {
180 #[allow(clippy::cast_possible_truncation)]
182 {
183 self.data.len() as u32
184 }
185 }
186
187 #[inline]
189 pub fn channel(&self, channel_index: u32) -> Option<&[S]> {
190 unsafe {
192 self.data.get(channel_index as usize).map(|data| {
193 slice_from_external_parts(*data as *const _, self.frames_count as usize)
194 })
195 }
196 }
197
198 #[inline]
200 pub fn channel_mut(&mut self, channel_index: u32) -> Option<&mut [S]> {
201 unsafe {
204 self.data.get(channel_index as usize).map(|data| {
205 slice_from_external_parts_mut(*data as *mut _, self.frames_count as usize)
206 })
207 }
208 }
209
210 #[inline]
212 pub fn iter(&self) -> InputChannelsIter<'_, S> {
213 InputChannelsIter {
214 data: self.data.iter(),
215 frames_count: self.frames_count,
216 }
217 }
218
219 #[inline]
221 pub fn iter_mut(&mut self) -> OutputChannelsIter<'_, S> {
222 OutputChannelsIter {
223 data: self.data.as_mut().iter_mut(),
224 frames_count: self.frames_count,
225 }
226 }
227
228 #[inline]
238 pub fn split_at_mut(&mut self, mid: u32) -> (OutputChannels<'_, S>, OutputChannels<'_, S>) {
239 let mid = mid as usize;
240 if mid >= self.data.len() {
241 return (
242 OutputChannels {
243 data: self.data,
244 frames_count: self.frames_count,
245 },
246 OutputChannels {
247 data: &mut [],
248 frames_count: self.frames_count,
249 },
250 );
251 }
252 let (left, right) = self.data.split_at_mut(mid);
254
255 (
256 OutputChannels {
257 data: left,
258 frames_count: self.frames_count,
259 },
260 OutputChannels {
261 data: right,
262 frames_count: self.frames_count,
263 },
264 )
265 }
266}
267impl<'a, T> IntoIterator for &'a OutputChannels<'a, T> {
268 type Item = &'a [T];
269 type IntoIter = InputChannelsIter<'a, T>;
270
271 #[inline]
272 fn into_iter(self) -> Self::IntoIter {
273 self.iter()
274 }
275}
276
277impl<'a, T> IntoIterator for &'a mut OutputChannels<'a, T> {
278 type Item = &'a mut [T];
279 type IntoIter = OutputChannelsIter<'a, T>;
280
281 #[inline]
282 fn into_iter(self) -> Self::IntoIter {
283 self.iter_mut()
284 }
285}
286
287impl<'a, T> IntoIterator for OutputChannels<'a, T> {
288 type Item = &'a mut [T];
289 type IntoIter = OutputChannelsIter<'a, T>;
290
291 #[inline]
292 fn into_iter(self) -> Self::IntoIter {
293 OutputChannelsIter {
294 data: self.data.as_mut().iter_mut(),
295 frames_count: self.frames_count,
296 }
297 }
298}
299
300pub struct OutputChannelsIter<'a, T> {
302 data: IterMut<'a, *mut T>,
303 frames_count: u32,
304}
305
306impl<'a, T> Iterator for OutputChannelsIter<'a, T> {
307 type Item = &'a mut [T];
308
309 #[inline]
310 fn next(&mut self) -> Option<Self::Item> {
311 self.data.next().map(|ptr| unsafe {
314 slice_from_external_parts_mut(*ptr as *mut _, self.frames_count as usize)
315 })
316 }
317
318 #[inline]
319 fn size_hint(&self) -> (usize, Option<usize>) {
320 self.data.size_hint()
321 }
322}
323
324impl<S> ExactSizeIterator for OutputChannelsIter<'_, S> {
325 #[inline]
326 fn len(&self) -> usize {
327 self.data.len()
328 }
329}