geng_rodio/source/
delay.rs1use std::time::Duration;
2
3use crate::{Sample, Source};
4
5pub 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#[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 #[inline]
36 pub fn inner(&self) -> &I {
37 &self.input
38 }
39
40 #[inline]
42 pub fn inner_mut(&mut self) -> &mut I {
43 &mut self.input
44 }
45
46 #[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}