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}