Skip to main content

clack_plugin/process/
audio.rs

1//! Various types related to accessing [`Audio`](super::Audio) buffers.
2
3mod error;
4mod input;
5mod output;
6mod pair;
7mod sample_type;
8
9pub use error::BufferError;
10pub use input::*;
11pub use output::*;
12pub use pair::*;
13pub use sample_type::SampleType;
14
15#[cfg(test)]
16#[allow(missing_docs)]
17pub mod tests {
18    use super::*;
19    use crate::prelude::Audio;
20    use clack_common::process::ConstantMask;
21    use clack_host::prelude::*;
22
23    fn get_audio<'a, const N: usize>(
24        ins: &'a mut [[f32; N]],
25        outs: &'a mut [[f32; N]],
26        input_ports: &'a mut AudioPorts,
27        output_ports: &'a mut AudioPorts,
28    ) -> Audio<'a> {
29        let input_buffers = input_ports.with_input_buffers([AudioPortBuffer {
30            latency: 0,
31            channels: AudioPortBufferType::f32_input_only(
32                ins.iter_mut().map(InputChannel::variable),
33            ),
34        }]);
35
36        let output_buffers = output_ports.with_output_buffers([AudioPortBuffer {
37            latency: 0,
38            channels: AudioPortBufferType::f32_output_only(
39                outs.iter_mut().map(|b| b.as_mut_slice()),
40            ),
41        }]);
42
43        let frames_count = input_buffers.min_available_frames_with(&output_buffers);
44
45        Audio {
46            inputs: input_buffers.as_raw_buffers(),
47            frames_count,
48            outputs: output_buffers.into_raw_buffers(),
49        }
50    }
51
52    #[test]
53    fn can_iterate_on_pairs() {
54        let mut ins = [[1f32; 4]; 2];
55        let mut outs = [[0f32; 4]; 2];
56
57        let mut input_ports = AudioPorts::with_capacity(2, 1);
58        let mut output_ports = AudioPorts::with_capacity(2, 1);
59
60        let mut audio = get_audio(&mut ins, &mut outs, &mut input_ports, &mut output_ports);
61        let mut ports = audio.port_pairs();
62        assert_eq!(ports.len(), 1);
63        assert_eq!(ports.size_hint(), (1, Some(1)));
64        let mut port = ports.next().unwrap();
65        assert!(ports.next().is_none());
66
67        let mut channels = port.channels().unwrap().into_f32().unwrap();
68        assert_eq!(channels.iter_mut().len(), 2);
69        assert_eq!(channels.iter_mut().size_hint(), (2, Some(2)));
70        let mut constant_mask = ConstantMask::FULLY_CONSTANT;
71        let mut total = 0;
72
73        for channel in channels {
74            let ChannelPair::InputOutput(i, o) = channel else {
75                panic!("Expected I/O channel")
76            };
77            o.copy_from_slice(i);
78            total += 1;
79            constant_mask.set_channel_constant(total, false);
80        }
81
82        port.output().unwrap().set_constant_mask(constant_mask);
83
84        assert_eq!(total, 2);
85        assert_eq!(ins, outs);
86    }
87
88    #[test]
89    fn can_access_pairs_with_indexes() {
90        let mut ins = [[1f32; 4]; 2];
91        let mut outs = [[0f32; 4]; 2];
92
93        let mut input_ports = AudioPorts::with_capacity(2, 1);
94        let mut output_ports = AudioPorts::with_capacity(2, 1);
95
96        let mut audio = get_audio(&mut ins, &mut outs, &mut input_ports, &mut output_ports);
97        assert_eq!(audio.port_pair_count(), 1);
98
99        let mut port = audio.port_pair(0).unwrap();
100        assert_eq!(port.channel_pair_count(), 2);
101
102        let mut channels = port.channels().unwrap().into_f32().unwrap();
103        assert_eq!(channels.channel_pair_count(), 2);
104
105        let mut constant_mask = ConstantMask::FULLY_CONSTANT;
106
107        for i in 0..port.channel_pair_count() {
108            let channel = channels.channel_pair(i).unwrap();
109            let ChannelPair::InputOutput(input, output) = channel else {
110                panic!("Expected I/O channel")
111            };
112            output.copy_from_slice(input);
113
114            constant_mask.set_channel_constant(i as u64, false);
115        }
116
117        port.output().unwrap().set_constant_mask(constant_mask);
118
119        assert_eq!(ins, outs);
120    }
121
122    #[test]
123    fn can_iterate_on_io() {
124        let mut ins = [[1f32; 4]; 2];
125        let mut outs = [[0f32; 4]; 2];
126
127        let mut input_ports = AudioPorts::with_capacity(2, 1);
128        let mut output_ports = AudioPorts::with_capacity(2, 1);
129
130        let mut audio = get_audio(&mut ins, &mut outs, &mut input_ports, &mut output_ports);
131
132        let mut ports = audio.input_ports();
133        assert_eq!(ports.len(), 1);
134        assert_eq!(ports.size_hint(), (1, Some(1)));
135        let port = ports.next().unwrap();
136        assert!(ports.next().is_none());
137
138        let channels = port.channels().unwrap().into_f32().unwrap();
139        assert_eq!(channels.iter().len(), 2);
140        assert_eq!(channels.iter().size_hint(), (2, Some(2)));
141        let mut total = 0;
142
143        for channel in channels {
144            assert!(channel.iter().all(|f| *f == 1.0));
145            total += 1;
146        }
147
148        assert_eq!(total, 2);
149
150        let mut ports = audio.output_ports();
151        assert_eq!(ports.len(), 1);
152        assert_eq!(ports.size_hint(), (1, Some(1)));
153        let mut port = ports.next().unwrap();
154        assert!(ports.next().is_none());
155
156        let mut channels = port.channels().unwrap().into_f32().unwrap();
157        assert_eq!(channels.iter_mut().len(), 2);
158        assert_eq!(channels.iter_mut().size_hint(), (2, Some(2)));
159        let mut total = 0;
160
161        for channel in channels {
162            channel.fill(1.0);
163            total += 1;
164        }
165
166        assert_eq!(total, 2);
167
168        assert_eq!(ins, outs);
169    }
170
171    #[test]
172    fn can_access_io_with_indexes() {
173        let mut ins = [[1f32; 4]; 2];
174        let mut outs = [[0f32; 4]; 2];
175
176        let mut input_ports = AudioPorts::with_capacity(2, 1);
177        let mut output_ports = AudioPorts::with_capacity(2, 1);
178
179        let mut audio = get_audio(&mut ins, &mut outs, &mut input_ports, &mut output_ports);
180        assert_eq!(audio.port_pair_count(), 1);
181
182        let port = audio.input_port(0).unwrap();
183        assert_eq!(port.channel_count(), 2);
184
185        let channels = port.channels().unwrap().into_f32().unwrap();
186        assert_eq!(channels.channel_count(), 2);
187
188        for i in 0..port.channel_count() {
189            let channel = channels.channel(i).unwrap();
190            assert!(channel.iter().all(|f| *f == 1.0));
191        }
192
193        let mut port = audio.output_port(0).unwrap();
194        assert_eq!(port.channel_count(), 2);
195
196        let mut channels = port.channels().unwrap().into_f32().unwrap();
197        assert_eq!(channels.channel_count(), 2);
198
199        let constant_mask = ConstantMask::FULLY_CONSTANT;
200
201        for i in 0..port.channel_count() {
202            let channel = channels.channel_mut(i).unwrap();
203            channel.fill(1.0);
204        }
205
206        port.set_constant_mask(constant_mask);
207
208        assert_eq!(ins, outs);
209    }
210}