rodio/source/
fadeout.rs

1use std::time::Duration;
2
3use crate::{Sample, Source};
4
5use super::{linear_ramp::linear_gain_ramp, LinearGainRamp, SeekError};
6
7/// Internal function that builds a `FadeOut` object.
8pub fn fadeout<I>(input: I, duration: Duration) -> FadeOut<I>
9where
10    I: Source,
11    I::Item: Sample,
12{
13    FadeOut {
14        input: linear_gain_ramp(input, duration, 1.0f32, 0.0f32, true),
15    }
16}
17
18/// Filter that modifies lowers the volume to silence over a time period.
19#[derive(Clone, Debug)]
20pub struct FadeOut<I> {
21    input: LinearGainRamp<I>,
22}
23
24impl<I> FadeOut<I>
25where
26    I: Source,
27    I::Item: Sample,
28{
29    /// Returns a reference to the inner source.
30    #[inline]
31    pub fn inner(&self) -> &I {
32        self.input.inner()
33    }
34
35    /// Returns a mutable reference to the inner source.
36    #[inline]
37    pub fn inner_mut(&mut self) -> &mut I {
38        self.input.inner_mut()
39    }
40
41    /// Returns the inner source.
42    #[inline]
43    pub fn into_inner(self) -> I {
44        self.input.into_inner()
45    }
46}
47
48impl<I> Iterator for FadeOut<I>
49where
50    I: Source,
51    I::Item: Sample,
52{
53    type Item = I::Item;
54
55    #[inline]
56    fn next(&mut self) -> Option<I::Item> {
57        self.input.next()
58    }
59
60    #[inline]
61    fn size_hint(&self) -> (usize, Option<usize>) {
62        self.input.size_hint()
63    }
64}
65
66impl<I> ExactSizeIterator for FadeOut<I>
67where
68    I: Source + ExactSizeIterator,
69    I::Item: Sample,
70{
71}
72
73impl<I> Source for FadeOut<I>
74where
75    I: Source,
76    I::Item: Sample,
77{
78    #[inline]
79    fn current_frame_len(&self) -> Option<usize> {
80        self.inner().current_frame_len()
81    }
82
83    #[inline]
84    fn channels(&self) -> u16 {
85        self.inner().channels()
86    }
87
88    #[inline]
89    fn sample_rate(&self) -> u32 {
90        self.inner().sample_rate()
91    }
92
93    #[inline]
94    fn total_duration(&self) -> Option<Duration> {
95        self.inner().total_duration()
96    }
97
98    #[inline]
99    fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
100        self.inner_mut().try_seek(pos)
101    }
102}