geng_rodio/source/
fadein.rs1use std::time::Duration;
2
3use crate::{Sample, Source};
4
5pub fn fadein<I>(input: I, duration: Duration) -> FadeIn<I>
7where
8 I: Source,
9 I::Item: Sample,
10{
11 let duration = duration.as_secs() * 1000000000 + duration.subsec_nanos() as u64;
12
13 FadeIn {
14 input,
15 remaining_ns: duration as f32,
16 total_ns: duration as f32,
17 }
18}
19
20#[derive(Clone, Debug)]
22pub struct FadeIn<I> {
23 input: I,
24 remaining_ns: f32,
25 total_ns: f32,
26}
27
28impl<I> FadeIn<I>
29where
30 I: Source,
31 I::Item: Sample,
32{
33 #[inline]
35 pub fn inner(&self) -> &I {
36 &self.input
37 }
38
39 #[inline]
41 pub fn inner_mut(&mut self) -> &mut I {
42 &mut self.input
43 }
44
45 #[inline]
47 pub fn into_inner(self) -> I {
48 self.input
49 }
50}
51
52impl<I> Iterator for FadeIn<I>
53where
54 I: Source,
55 I::Item: Sample,
56{
57 type Item = I::Item;
58
59 #[inline]
60 fn next(&mut self) -> Option<I::Item> {
61 if self.remaining_ns <= 0.0 {
62 return self.input.next();
63 }
64
65 let factor = 1.0 - self.remaining_ns / self.total_ns;
66 self.remaining_ns -=
67 1000000000.0 / (self.input.sample_rate() as f32 * self.channels() as f32);
68 self.input.next().map(|value| value.amplify(factor))
69 }
70
71 #[inline]
72 fn size_hint(&self) -> (usize, Option<usize>) {
73 self.input.size_hint()
74 }
75}
76
77impl<I> ExactSizeIterator for FadeIn<I>
78where
79 I: Source + ExactSizeIterator,
80 I::Item: Sample,
81{
82}
83
84impl<I> Source for FadeIn<I>
85where
86 I: Source,
87 I::Item: Sample,
88{
89 #[inline]
90 fn current_frame_len(&self) -> Option<usize> {
91 self.input.current_frame_len()
92 }
93
94 #[inline]
95 fn channels(&self) -> u16 {
96 self.input.channels()
97 }
98
99 #[inline]
100 fn sample_rate(&self) -> u32 {
101 self.input.sample_rate()
102 }
103
104 #[inline]
105 fn total_duration(&self) -> Option<Duration> {
106 self.input.total_duration()
107 }
108}