geng_rodio/source/
channel_volume.rs1use std::time::Duration;
2
3use crate::{Sample, Source};
4
5#[derive(Clone, Debug)]
8pub struct ChannelVolume<I>
9where
10 I: Source,
11 I::Item: Sample,
12{
13 input: I,
14 channel_volumes: Vec<f32>,
16 current_channel: usize,
18 current_sample: Option<I::Item>,
19}
20
21impl<I> ChannelVolume<I>
22where
23 I: Source,
24 I::Item: Sample,
25{
26 pub fn new(mut input: I, channel_volumes: Vec<f32>) -> ChannelVolume<I>
27 where
28 I: Source,
29 I::Item: Sample,
30 {
31 let mut sample = None;
32 for _ in 0..input.channels() {
33 if let Some(s) = input.next() {
34 sample = Some(
35 sample
36 .get_or_insert_with(I::Item::zero_value)
37 .saturating_add(s),
38 );
39 }
40 }
41 ChannelVolume {
42 input,
43 channel_volumes,
44 current_channel: 0,
45 current_sample: sample,
46 }
47 }
48
49 pub fn set_volume(&mut self, channel: usize, volume: f32) {
52 self.channel_volumes[channel] = volume;
53 }
54
55 #[inline]
57 pub fn inner(&self) -> &I {
58 &self.input
59 }
60
61 #[inline]
63 pub fn inner_mut(&mut self) -> &mut I {
64 &mut self.input
65 }
66
67 #[inline]
69 pub fn into_inner(self) -> I {
70 self.input
71 }
72}
73
74impl<I> Iterator for ChannelVolume<I>
75where
76 I: Source,
77 I::Item: Sample,
78{
79 type Item = I::Item;
80
81 #[inline]
82 fn next(&mut self) -> Option<I::Item> {
83 let ret = self
85 .current_sample
86 .map(|sample| sample.amplify(self.channel_volumes[self.current_channel]));
87 self.current_channel += 1;
88 if self.current_channel >= self.channel_volumes.len() {
89 self.current_channel = 0;
90 self.current_sample = None;
91 for _ in 0..self.input.channels() {
92 if let Some(s) = self.input.next() {
93 self.current_sample = Some(
94 self.current_sample
95 .get_or_insert_with(I::Item::zero_value)
96 .saturating_add(s),
97 );
98 }
99 }
100 }
101 ret
102 }
103
104 #[inline]
105 fn size_hint(&self) -> (usize, Option<usize>) {
106 self.input.size_hint()
107 }
108}
109
110impl<I> ExactSizeIterator for ChannelVolume<I>
111where
112 I: Source + ExactSizeIterator,
113 I::Item: Sample,
114{
115}
116
117impl<I> Source for ChannelVolume<I>
118where
119 I: Source,
120 I::Item: Sample,
121{
122 #[inline]
123 fn current_frame_len(&self) -> Option<usize> {
124 self.input.current_frame_len()
125 }
126
127 #[inline]
128 fn channels(&self) -> u16 {
129 self.channel_volumes.len() as u16
130 }
131
132 #[inline]
133 fn sample_rate(&self) -> u32 {
134 self.input.sample_rate()
135 }
136
137 #[inline]
138 fn total_duration(&self) -> Option<Duration> {
139 self.input.total_duration()
140 }
141}