1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3
4#[cfg(feature = "alloc")]
5extern crate alloc;
6
7pub mod direct;
9pub mod number_to_float;
12#[cfg(feature = "alloc")]
14pub mod owned;
15
16pub mod dummy;
18
19mod slicetools;
20
21use core::error::Error;
22use core::fmt;
23
24pub mod adapter_to_float;
25
26#[derive(Debug)]
29pub enum SizeError {
30 ChannelsContainer { actual: usize, required: usize },
35 FramesContainer { actual: usize, required: usize },
40 ChannelBuffer {
44 index: usize,
45 actual: usize,
46 required: usize,
47 },
48 FrameBuffer {
52 index: usize,
53 actual: usize,
54 required: usize,
55 },
56 Total { actual: usize, required: usize },
65 Mask { actual: usize, required: usize },
72}
73
74impl Error for SizeError {}
75
76impl fmt::Display for SizeError {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 match self {
79 SizeError::ChannelsContainer { actual, required } => write!(
80 f,
81 "Channels container is too short, got: {}, required: {}",
82 actual, required
83 ),
84 SizeError::FramesContainer { actual, required } => write!(
85 f,
86 "Frames container is too short, got: {}, required: {}",
87 actual, required
88 ),
89 SizeError::ChannelBuffer {
90 index,
91 actual,
92 required,
93 } => write!(
94 f,
95 "Channel buffer {} is too short for requested frame count, got: {}, required: {}",
96 index, actual, required
97 ),
98 SizeError::FrameBuffer {
99 index,
100 actual,
101 required,
102 } => write!(
103 f,
104 "Frame buffer {} is too short for requested channel count, got: {}, required: {}",
105 index, actual, required
106 ),
107 SizeError::Total { actual, required } => write!(
108 f,
109 "Flat buffer is too short for requested dimensions, got: {}, required: {}",
110 actual, required
111 ),
112 SizeError::Mask { actual, required } => write!(
113 f,
114 "Mask length is invalid for channel count, got: {}, required: {}",
115 actual, required
116 ),
117 }
118 }
119}
120
121macro_rules! implement_size_getters {
122 () => {
123 fn channels(&self) -> usize {
124 self.channels
125 }
126
127 fn frames(&self) -> usize {
128 self.frames
129 }
130 };
131}
132pub(crate) use implement_size_getters;
133
134macro_rules! check_slice_length {
135 ($channels:expr , $frames:expr, $length:expr ) => {
136 if $length < $frames * $channels {
137 return Err(SizeError::Total {
138 actual: $length,
139 required: $frames * $channels,
140 });
141 }
142 };
143 ($channels:expr , $frames:expr, $length:expr, $elements_per_sample:expr) => {
144 if $length < $frames * $channels * $elements_per_sample {
145 return Err(SizeError::Total {
146 actual: $length,
147 required: $frames * $channels * $elements_per_sample,
148 });
149 }
150 };
151}
152pub(crate) use check_slice_length;
153
154#[cfg(test)]
155mod tests {
156 use audioadapter::AdapterMut;
157
158 fn prepare_test_data(buffer: &mut dyn AdapterMut<u32>) {
159 for channel in 0..buffer.channels() {
160 for frame in 0..buffer.frames() {
161 let value = (100 * channel + frame) as u32;
162 buffer.write_sample(channel, frame, &value);
163 }
164 }
165 }
166
167 pub(crate) fn check_copy_within(buffer: &mut dyn AdapterMut<u32>) {
168 assert!(buffer.channels() > 1, "Too few channels to run tests");
169 assert!(buffer.frames() > 8, "Too few frames to run test");
170 prepare_test_data(buffer);
172 assert_eq!(buffer.copy_frames_within(1, 5, 3), Some(3));
173 check_copy_result(buffer, 1, 5, 3);
174
175 prepare_test_data(buffer);
177 assert_eq!(buffer.copy_frames_within(5, 1, 3), Some(3));
178 check_copy_result(buffer, 5, 1, 3);
179
180 prepare_test_data(buffer);
182 assert_eq!(buffer.copy_frames_within(1, 3, 5), Some(5));
183 check_copy_result(buffer, 1, 3, 5);
184
185 prepare_test_data(buffer);
187 assert_eq!(buffer.copy_frames_within(3, 1, 5), Some(5));
188 check_copy_result(buffer, 3, 1, 5);
189 }
190
191 fn check_copy_result(buffer: &dyn AdapterMut<u32>, src: usize, dest: usize, count: usize) {
192 for channel in 0..buffer.channels() {
193 for frame in 0..buffer.frames() {
194 let copied_frame = if frame >= dest && frame < dest + count {
195 frame + src - dest
196 } else {
197 frame
198 };
199 let expected_value = (100 * channel + copied_frame) as u32;
200 assert_eq!(
201 buffer.read_sample(channel, frame),
202 Some(expected_value),
203 "Wrong value at ch {}, frame {}",
204 channel,
205 frame
206 );
207 }
208 }
209 }
210}