rodio/source/
distortion.rs

1use std::time::Duration;
2
3use super::SeekError;
4use crate::common::{ChannelCount, SampleRate};
5use crate::Source;
6
7/// Internal function that builds a `Distortion` object.
8pub(crate) fn distortion<I>(input: I, gain: f32, threshold: f32) -> Distortion<I>
9where
10    I: Source,
11{
12    Distortion {
13        input,
14        gain,
15        threshold,
16    }
17}
18
19/// Filter that applies a distortion effect to the source.
20#[derive(Clone, Debug)]
21pub struct Distortion<I> {
22    input: I,
23    gain: f32,
24    threshold: f32,
25}
26
27impl<I> Distortion<I> {
28    /// Modifies the distortion gain.
29    #[inline]
30    pub fn set_gain(&mut self, gain: f32) {
31        self.gain = gain;
32    }
33
34    /// Modifies the distortion threshold.
35    #[inline]
36    pub fn set_threshold(&mut self, threshold: f32) {
37        self.threshold = threshold;
38    }
39
40    /// Returns a reference to the inner source.
41    #[inline]
42    pub fn inner(&self) -> &I {
43        &self.input
44    }
45
46    /// Returns a mutable reference to the inner source.
47    #[inline]
48    pub fn inner_mut(&mut self) -> &mut I {
49        &mut self.input
50    }
51
52    /// Returns the inner source.
53    #[inline]
54    pub fn into_inner(self) -> I {
55        self.input
56    }
57}
58
59impl<I> Iterator for Distortion<I>
60where
61    I: Source,
62{
63    type Item = I::Item;
64
65    #[inline]
66    fn next(&mut self) -> Option<Self::Item> {
67        self.input.next().map(|value| {
68            let v = value * self.gain;
69            let t = self.threshold;
70            v.clamp(-t, t)
71        })
72    }
73
74    #[inline]
75    fn size_hint(&self) -> (usize, Option<usize>) {
76        self.input.size_hint()
77    }
78}
79
80impl<I> ExactSizeIterator for Distortion<I> where I: Source + ExactSizeIterator {}
81
82impl<I> Source for Distortion<I>
83where
84    I: Source,
85{
86    #[inline]
87    fn current_span_len(&self) -> Option<usize> {
88        self.input.current_span_len()
89    }
90
91    #[inline]
92    fn channels(&self) -> ChannelCount {
93        self.input.channels()
94    }
95
96    #[inline]
97    fn sample_rate(&self) -> SampleRate {
98        self.input.sample_rate()
99    }
100
101    #[inline]
102    fn total_duration(&self) -> Option<Duration> {
103        self.input.total_duration()
104    }
105
106    #[inline]
107    fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
108        self.input.try_seek(pos)
109    }
110}