geng_rodio/source/
samples_converter.rs

1use std::marker::PhantomData;
2use std::time::Duration;
3
4use crate::{Sample, Source};
5use cpal::{FromSample, Sample as CpalSample};
6
7/// An iterator that reads from a `Source` and converts the samples to a specific rate and
8/// channels count.
9///
10/// It implements `Source` as well, but all the data is guaranteed to be in a single frame whose
11/// channels and samples rate have been passed to `new`.
12#[derive(Clone)]
13pub struct SamplesConverter<I, D> {
14    inner: I,
15    dest: PhantomData<D>,
16}
17
18impl<I, D> SamplesConverter<I, D> {
19    #[inline]
20    pub fn new(input: I) -> SamplesConverter<I, D> {
21        SamplesConverter {
22            inner: input,
23            dest: PhantomData,
24        }
25    }
26
27    /// Returns a reference to the inner source.
28    #[inline]
29    pub fn inner(&self) -> &I {
30        &self.inner
31    }
32
33    /// Returns a mutable reference to the inner source.
34    #[inline]
35    pub fn inner_mut(&mut self) -> &mut I {
36        &mut self.inner
37    }
38
39    /// Returns the inner source.
40    #[inline]
41    pub fn into_inner(self) -> I {
42        self.inner
43    }
44}
45
46impl<I, D> Iterator for SamplesConverter<I, D>
47where
48    I: Source,
49    I::Item: Sample,
50    D: FromSample<I::Item> + Sample,
51{
52    type Item = D;
53
54    #[inline]
55    fn next(&mut self) -> Option<D> {
56        self.inner.next().map(|s| CpalSample::from_sample(s))
57    }
58
59    #[inline]
60    fn size_hint(&self) -> (usize, Option<usize>) {
61        self.inner.size_hint()
62    }
63}
64
65impl<I, D> ExactSizeIterator for SamplesConverter<I, D>
66where
67    I: Source + ExactSizeIterator,
68    I::Item: Sample,
69    D: FromSample<I::Item> + Sample,
70{
71}
72
73impl<I, D> Source for SamplesConverter<I, D>
74where
75    I: Source,
76    I::Item: Sample,
77    D: FromSample<I::Item> + Sample,
78{
79    #[inline]
80    fn current_frame_len(&self) -> Option<usize> {
81        self.inner.current_frame_len()
82    }
83
84    #[inline]
85    fn channels(&self) -> u16 {
86        self.inner.channels()
87    }
88
89    #[inline]
90    fn sample_rate(&self) -> u32 {
91        self.inner.sample_rate()
92    }
93
94    #[inline]
95    fn total_duration(&self) -> Option<Duration> {
96        self.inner.total_duration()
97    }
98}