sample/slice.rs
1//! This module provides various helper functions for performing operations on slices of frames.
2
3use {Box, Frame, Sample, ToSampleSlice, ToSampleSliceMut, ToBoxedSampleSlice, ToFrameSlice,
4 ToFrameSliceMut, ToBoxedFrameSlice, FromSampleSlice, FromSampleSliceMut,
5 FromBoxedSampleSlice, FromFrameSlice, FromFrameSliceMut, FromBoxedFrameSlice};
6
7
8///// Conversion Functions
9/////
10///// The following functions wrap the various DSP slice conversion traits for convenience.
11
12
13/// Converts the given slice into a slice of `Frame`s.
14///
15/// Returns `None` if the number of channels in a single frame `F` is not a multiple of the number
16/// of samples in the given slice.
17///
18/// This is a convenience function that wraps the `ToFrameSlice` trait.
19///
20/// # Examples
21///
22/// ```
23/// extern crate sample;
24///
25/// fn main() {
26/// let foo = &[0.0, 0.5, 0.0, -0.5][..];
27/// let bar = sample::slice::to_frame_slice(foo);
28/// assert_eq!(bar, Some(&[[0.0, 0.5], [0.0, -0.5]][..]));
29///
30/// let foo = &[0.0, 0.5, 0.0][..];
31/// let bar = sample::slice::to_frame_slice(foo);
32/// assert_eq!(bar, None::<&[[f32; 2]]>);
33/// }
34/// ```
35pub fn to_frame_slice<'a, T, F>(slice: T) -> Option<&'a [F]>
36where
37 F: Frame,
38 T: ToFrameSlice<'a, F>,
39{
40 slice.to_frame_slice()
41}
42
43/// Converts the given mutable slice into a mutable slice of `Frame`s.
44///
45/// Returns `None` if the number of channels in a single frame `F` is not a multiple of the number
46/// of samples in the given slice.
47///
48/// This is a convenience function that wraps the `ToFrameSliceMut` trait.
49///
50/// # Examples
51///
52/// ```
53/// extern crate sample;
54///
55/// fn main() {
56/// let foo = &mut [0.0, 0.5, 0.0, -0.5][..];
57/// let bar = sample::slice::to_frame_slice_mut(foo);
58/// assert_eq!(bar, Some(&mut [[0.0, 0.5], [0.0, -0.5]][..]));
59///
60/// let foo = &mut [0.0, 0.5, 0.0][..];
61/// let bar = sample::slice::to_frame_slice_mut(foo);
62/// assert_eq!(bar, None::<&mut [[f32; 2]]>);
63/// }
64/// ```
65pub fn to_frame_slice_mut<'a, T, F>(slice: T) -> Option<&'a mut [F]>
66where
67 F: Frame,
68 T: ToFrameSliceMut<'a, F>,
69{
70 slice.to_frame_slice_mut()
71}
72
73/// Converts the given boxed slice into a boxed slice of `Frame`s.
74///
75/// Returns `None` if the number of channels in a single frame `F` is not a multiple of the number
76/// of samples in the given slice.
77///
78/// This is a convenience function that wraps the `ToBoxedFrameSlice` trait.
79///
80/// # Examples
81///
82/// ```
83/// extern crate sample;
84///
85/// fn main() {
86/// let foo = vec![0.0, 0.5, 0.0, -0.5].into_boxed_slice();
87/// let bar: Box<[[f32; 2]]> = sample::slice::to_boxed_frame_slice(foo).unwrap();
88/// assert_eq!(bar.into_vec(), vec![[0.0, 0.5], [0.0, -0.5]]);
89///
90/// let foo = vec![0.0, 0.5, 0.0].into_boxed_slice();
91/// let bar = sample::slice::to_boxed_frame_slice(foo);
92/// assert_eq!(bar, None::<Box<[[f32; 2]]>>);
93/// }
94/// ```
95pub fn to_boxed_frame_slice<T, F>(slice: T) -> Option<Box<[F]>>
96where
97 F: Frame,
98 T: ToBoxedFrameSlice<F>,
99{
100 slice.to_boxed_frame_slice()
101}
102
103/// Converts the given slice into a slice of `Sample`s.
104///
105/// This is a convenience function that wraps the `ToSampleSlice` trait.
106///
107/// # Examples
108///
109/// ```
110/// extern crate sample;
111///
112/// fn main() {
113/// let foo = &[[0.0, 0.5], [0.0, -0.5]][..];
114/// let bar = sample::slice::to_sample_slice(foo);
115/// assert_eq!(bar, &[0.0, 0.5, 0.0, -0.5][..]);
116/// }
117/// ```
118pub fn to_sample_slice<'a, T, S>(slice: T) -> &'a [S]
119where
120 S: Sample,
121 T: ToSampleSlice<'a, S>,
122{
123 slice.to_sample_slice()
124}
125
126/// Converts the given mutable slice of `Frame`s into a mutable slice of `Sample`s.
127///
128/// This is a convenience function that wraps the `ToSampleSliceMut` trait.
129///
130/// # Examples
131///
132/// ```
133/// extern crate sample;
134///
135/// fn main() {
136/// let foo = &mut [[0.0, 0.5], [0.0, -0.5]][..];
137/// let bar = sample::slice::to_sample_slice_mut(foo);
138/// assert_eq!(bar, &mut [0.0, 0.5, 0.0, -0.5][..]);
139/// }
140/// ```
141pub fn to_sample_slice_mut<'a, T, S>(slice: T) -> &'a mut [S]
142where
143 S: Sample,
144 T: ToSampleSliceMut<'a, S>,
145{
146 slice.to_sample_slice_mut()
147}
148
149/// Converts the given boxed slice into a boxed slice of `Sample`s.
150///
151/// This is a convenience function that wraps the `ToBoxedSampleSlice` trait.
152///
153/// # Examples
154///
155/// ```
156/// extern crate sample;
157///
158/// fn main() {
159/// let foo = vec![[0.0, 0.5], [0.0, -0.5]].into_boxed_slice();
160/// let bar = sample::slice::to_boxed_sample_slice(foo);
161/// assert_eq!(bar.into_vec(), vec![0.0, 0.5, 0.0, -0.5]);
162/// }
163/// ```
164pub fn to_boxed_sample_slice<T, S>(slice: T) -> Box<[S]>
165where
166 S: Sample,
167 T: ToBoxedSampleSlice<S>,
168{
169 slice.to_boxed_sample_slice()
170}
171
172/// Converts the given slice of `Sample`s into some slice `T`.
173///
174/// Returns `None` if the number of channels in a single frame is not a multiple of the number of
175/// samples in the given slice.
176///
177/// This is a convenience function that wraps the `FromSampleSlice` trait.
178///
179/// # Examples
180///
181/// ```
182/// extern crate sample;
183///
184/// fn main() {
185/// let foo = &[0.0, 0.5, 0.0, -0.5][..];
186/// let bar: Option<&_> = sample::slice::from_sample_slice(foo);
187/// assert_eq!(bar, Some(&[[0.0, 0.5], [0.0, -0.5]][..]));
188/// }
189/// ```
190pub fn from_sample_slice<'a, T, S>(slice: &'a [S]) -> Option<T>
191where
192 S: Sample,
193 T: FromSampleSlice<'a, S>,
194{
195 T::from_sample_slice(slice)
196}
197
198/// Converts the given mutable slice of `Sample`s into some mutable slice `T`.
199///
200/// Returns `None` if the number of channels in a single frame is not a multiple of the number of
201/// samples in the given slice.
202///
203/// This is a convenience function that wraps the `FromSampleSliceMut` trait.
204///
205/// # Examples
206///
207/// ```
208/// extern crate sample;
209///
210/// fn main() {
211/// let foo = &mut [0.0, 0.5, 0.0, -0.5][..];
212/// let bar: Option<&mut _> = sample::slice::from_sample_slice_mut(foo);
213/// assert_eq!(bar, Some(&mut [[0.0, 0.5], [0.0, -0.5]][..]));
214/// }
215/// ```
216pub fn from_sample_slice_mut<'a, T, S>(slice: &'a mut [S]) -> Option<T>
217where
218 S: Sample,
219 T: FromSampleSliceMut<'a, S>,
220{
221 T::from_sample_slice_mut(slice)
222}
223
224/// Converts the given boxed slice of `Sample`s into some slice `T`.
225///
226/// Returns `None` if the number of channels in a single frame is not a multiple of the number of
227/// samples in the given slice.
228///
229/// This is a convenience function that wraps the `FromBoxedSampleSlice` trait.
230///
231/// # Examples
232///
233/// ```
234/// extern crate sample;
235///
236/// fn main() {
237/// let foo = vec![0.0, 0.5, 0.0, -0.5].into_boxed_slice();
238/// let bar: Box<[[f32; 2]]> = sample::slice::from_boxed_sample_slice(foo).unwrap();
239/// assert_eq!(bar.into_vec(), vec![[0.0, 0.5], [0.0, -0.5]]);
240/// }
241/// ```
242pub fn from_boxed_sample_slice<T, S>(slice: Box<[S]>) -> Option<T>
243where
244 S: Sample,
245 T: FromBoxedSampleSlice<S>,
246{
247 T::from_boxed_sample_slice(slice)
248}
249
250/// Converts the given slice of `Frame`s into some slice `T`.
251///
252/// This is a convenience function that wraps the `FromFrameSlice` trait.
253///
254/// # Examples
255///
256/// ```
257/// extern crate sample;
258///
259/// fn main() {
260/// let foo = &[[0.0, 0.5], [0.0, -0.5]][..];
261/// let bar: &[f32] = sample::slice::from_frame_slice(foo);
262/// assert_eq!(bar, &[0.0, 0.5, 0.0, -0.5][..]);
263/// }
264/// ```
265pub fn from_frame_slice<'a, T, F>(slice: &'a [F]) -> T
266where
267 F: Frame,
268 T: FromFrameSlice<'a, F>,
269{
270 T::from_frame_slice(slice)
271}
272
273/// Converts the given slice of mutable `Frame`s into some mutable slice `T`.
274///
275/// This is a convenience function that wraps the `FromFrameSliceMut` trait.
276///
277/// # Examples
278///
279/// ```
280/// extern crate sample;
281///
282/// fn main() {
283/// let foo = &mut [[0.0, 0.5], [0.0, -0.5]][..];
284/// let bar: &mut [f32] = sample::slice::from_frame_slice_mut(foo);
285/// assert_eq!(bar, &mut [0.0, 0.5, 0.0, -0.5][..]);
286/// }
287/// ```
288pub fn from_frame_slice_mut<'a, T, F>(slice: &'a mut [F]) -> T
289where
290 F: Frame,
291 T: FromFrameSliceMut<'a, F>,
292{
293 T::from_frame_slice_mut(slice)
294}
295
296/// Converts the given boxed slice of `Frame`s into some slice `T`.
297///
298/// This is a convenience function that wraps the `FromBoxedFrameSlice` trait.
299///
300/// # Examples
301///
302/// ```
303/// extern crate sample;
304///
305/// fn main() {
306/// let foo = vec![[0.0, 0.5], [0.0, -0.5]].into_boxed_slice();
307/// let bar: Box<[f32]> = sample::slice::from_boxed_frame_slice(foo);
308/// assert_eq!(bar.into_vec(), vec![0.0, 0.5, 0.0, -0.5]);
309/// }
310/// ```
311pub fn from_boxed_frame_slice<T, F>(slice: Box<[F]>) -> T
312where
313 F: Frame,
314 T: FromBoxedFrameSlice<F>,
315{
316 T::from_boxed_frame_slice(slice)
317}
318
319
320///// Utility Functions
321
322
323/// Mutate every element in the slice with the given function.
324#[inline]
325pub fn map_in_place<F, M>(a: &mut [F], mut map: M)
326where
327 M: FnMut(F) -> F,
328 F: Frame,
329{
330 for f in a {
331 *f = map(*f);
332 }
333}
334
335/// Sets the slice of frames at the associated `Sample`'s equilibrium value.
336#[inline]
337pub fn equilibrium<F>(a: &mut [F])
338where
339 F: Frame,
340{
341 map_in_place(a, |_| F::equilibrium())
342}
343
344/// Mutate every frame in slice `a` while reading from each frame in slice `b` in lock-step using
345/// the given function.
346///
347/// **Panics** if the length of `b` is not equal to the length of `a`.
348#[inline]
349pub fn zip_map_in_place<FA, FB, M>(a: &mut [FA], b: &[FB], zip_map: M)
350where
351 FA: Frame,
352 FB: Frame,
353 M: FnMut(FA, FB) -> FA,
354{
355 assert_eq!(a.len(), b.len());
356
357 // We've asserted that the lengths are equal so we don't need bounds checking.
358 unsafe {
359 zip_map_in_place_unchecked(a, b, zip_map);
360 }
361}
362
363/// Writes every sample in slice `b` to slice `a`.
364///
365/// **Panics** if the slice lengths differ.
366#[inline]
367pub fn write<F>(a: &mut [F], b: &[F])
368where
369 F: Frame,
370{
371 zip_map_in_place(a, b, |_, b| b);
372}
373
374/// Adds every sample in slice `b` to every sample in slice `a` respectively.
375#[inline]
376pub fn add_in_place<FA, FB>(a: &mut [FA], b: &[FB])
377where
378 FA: Frame,
379 FB: Frame<Sample = <FA::Sample as Sample>::Signed, NumChannels = FA::NumChannels>,
380{
381 zip_map_in_place(a, b, |a, b| a.add_amp(b));
382}
383
384/// Scale the amplitude of each frame in `b` by `amp_per_channel` before summing it onto `a`.
385#[inline]
386pub fn add_in_place_with_amp_per_channel<FA, FB, A>(a: &mut [FA], b: &[FB], amp_per_channel: A)
387where
388 FA: Frame,
389 FB: Frame<Sample = <FA::Sample as Sample>::Signed, NumChannels = FA::NumChannels>,
390 A: Frame<Sample = <FB::Sample as Sample>::Float, NumChannels = FB::NumChannels>,
391{
392 zip_map_in_place(a, b, |af, bf| af.add_amp(bf.mul_amp(amp_per_channel)));
393}
394
395/// Mutate every element in slice `a` while reading from each element from slice `b` in lock-step
396/// using the given function.
397///
398/// This function does not check that the slices are the same length and will crash horrifically on
399/// index-out-of-bounds.
400#[inline]
401unsafe fn zip_map_in_place_unchecked<FA, FB, M>(a: &mut [FA], b: &[FB], mut zip_map: M)
402where
403 FA: Frame,
404 FB: Frame,
405 M: FnMut(FA, FB) -> FA,
406{
407 for i in 0..a.len() {
408 *a.get_unchecked_mut(i) = zip_map(*a.get_unchecked(i), *b.get_unchecked(i));
409 }
410}