geng_rodio/source/
delay.rs

1use std::time::Duration;
2
3use crate::{Sample, Source};
4
5/// Internal function that builds a `Delay` object.
6pub fn delay<I>(input: I, duration: Duration) -> Delay<I>
7where
8    I: Source,
9    I::Item: Sample,
10{
11    let duration_ns = duration.as_secs() * 1000000000 + duration.subsec_nanos() as u64;
12    let samples = duration_ns * input.sample_rate() as u64 / 1000000000 * input.channels() as u64;
13
14    Delay {
15        input,
16        remaining_samples: samples as usize,
17        requested_duration: duration,
18    }
19}
20
21/// A source that delays the given source by a certain amount.
22#[derive(Clone, Debug)]
23pub struct Delay<I> {
24    input: I,
25    remaining_samples: usize,
26    requested_duration: Duration,
27}
28
29impl<I> Delay<I>
30where
31    I: Source,
32    I::Item: Sample,
33{
34    /// Returns a reference to the inner source.
35    #[inline]
36    pub fn inner(&self) -> &I {
37        &self.input
38    }
39
40    /// Returns a mutable reference to the inner source.
41    #[inline]
42    pub fn inner_mut(&mut self) -> &mut I {
43        &mut self.input
44    }
45
46    /// Returns the inner source.
47    #[inline]
48    pub fn into_inner(self) -> I {
49        self.input
50    }
51}
52
53impl<I> Iterator for Delay<I>
54where
55    I: Source,
56    I::Item: Sample,
57{
58    type Item = <I as Iterator>::Item;
59
60    #[inline]
61    fn next(&mut self) -> Option<<I as Iterator>::Item> {
62        if self.remaining_samples >= 1 {
63            self.remaining_samples -= 1;
64            Some(Sample::zero_value())
65        } else {
66            self.input.next()
67        }
68    }
69
70    #[inline]
71    fn size_hint(&self) -> (usize, Option<usize>) {
72        let (min, max) = self.input.size_hint();
73        (
74            min + self.remaining_samples,
75            max.map(|v| v + self.remaining_samples),
76        )
77    }
78}
79
80impl<I> Source for Delay<I>
81where
82    I: Iterator + Source,
83    I::Item: Sample,
84{
85    #[inline]
86    fn current_frame_len(&self) -> Option<usize> {
87        self.input
88            .current_frame_len()
89            .map(|val| val + self.remaining_samples)
90    }
91
92    #[inline]
93    fn channels(&self) -> u16 {
94        self.input.channels()
95    }
96
97    #[inline]
98    fn sample_rate(&self) -> u32 {
99        self.input.sample_rate()
100    }
101
102    #[inline]
103    fn total_duration(&self) -> Option<Duration> {
104        self.input
105            .total_duration()
106            .map(|val| val + self.requested_duration)
107    }
108}