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