1use std::time::Duration;
2
3use super::{linear_ramp::linear_gain_ramp, LinearGainRamp, SeekError};
4use crate::common::{ChannelCount, SampleRate};
5use crate::Source;
6
7pub fn fadeout<I>(input: I, duration: Duration) -> FadeOut<I>
9where
10 I: Source,
11{
12 FadeOut {
13 input: linear_gain_ramp(input, duration, 1.0f32, 0.0f32, true),
14 }
15}
16
17#[derive(Clone, Debug)]
19pub struct FadeOut<I> {
20 input: LinearGainRamp<I>,
21}
22
23impl<I> FadeOut<I>
24where
25 I: Source,
26{
27 #[inline]
29 pub fn inner(&self) -> &I {
30 self.input.inner()
31 }
32
33 #[inline]
35 pub fn inner_mut(&mut self) -> &mut I {
36 self.input.inner_mut()
37 }
38
39 #[inline]
41 pub fn into_inner(self) -> I {
42 self.input.into_inner()
43 }
44}
45
46impl<I> Iterator for FadeOut<I>
47where
48 I: Source,
49{
50 type Item = I::Item;
51
52 #[inline]
53 fn next(&mut self) -> Option<I::Item> {
54 self.input.next()
55 }
56
57 #[inline]
58 fn size_hint(&self) -> (usize, Option<usize>) {
59 self.input.size_hint()
60 }
61}
62
63impl<I> ExactSizeIterator for FadeOut<I> where I: Source + ExactSizeIterator {}
64
65impl<I> Source for FadeOut<I>
66where
67 I: Source,
68{
69 #[inline]
70 fn current_span_len(&self) -> Option<usize> {
71 self.inner().current_span_len()
72 }
73
74 #[inline]
75 fn channels(&self) -> ChannelCount {
76 self.inner().channels()
77 }
78
79 #[inline]
80 fn sample_rate(&self) -> SampleRate {
81 self.inner().sample_rate()
82 }
83
84 #[inline]
85 fn total_duration(&self) -> Option<Duration> {
86 self.inner().total_duration()
87 }
88
89 #[inline]
90 fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
91 self.inner_mut().try_seek(pos)
92 }
93}