rodio/source/
channel_volume.rs1use std::time::Duration;
2
3use super::SeekError;
4use crate::common::{ChannelCount, SampleRate};
5use crate::{Float, Sample, Source};
6
7#[derive(Clone, Debug)]
10pub struct ChannelVolume<I>
11where
12 I: Source,
13{
14 input: I,
15 channel_volumes: Vec<Float>,
16 current_channel: usize,
17 current_sample: Option<Sample>,
18}
19
20impl<I> ChannelVolume<I>
21where
22 I: Source,
23{
24 pub fn new(input: I, channel_volumes: Vec<Float>) -> ChannelVolume<I> {
28 let channel_count = channel_volumes.len(); ChannelVolume {
30 input,
31 channel_volumes,
32 current_channel: channel_count,
33 current_sample: None,
34 }
35 }
36
37 pub fn set_volume(&mut self, channel: usize, volume: Float) {
40 self.channel_volumes[channel] = volume;
41 }
42
43 #[inline]
45 pub fn inner(&self) -> &I {
46 &self.input
47 }
48
49 #[inline]
51 pub fn inner_mut(&mut self) -> &mut I {
52 &mut self.input
53 }
54
55 #[inline]
57 pub fn into_inner(self) -> I {
58 self.input
59 }
60}
61
62impl<I> Iterator for ChannelVolume<I>
63where
64 I: Source,
65{
66 type Item = Sample;
67
68 #[inline]
69 fn next(&mut self) -> Option<Self::Item> {
70 if self.current_channel >= self.channel_volumes.len() {
72 self.current_channel = 0;
73 self.current_sample = None;
74 let num_channels = self.input.channels();
75 for _ in 0..num_channels.get() {
76 if let Some(s) = self.input.next() {
77 self.current_sample = Some(self.current_sample.unwrap_or(0.0) + s);
78 }
79 }
80 self.current_sample.map(|s| s / num_channels.get() as Float);
81 }
82 let result = self
83 .current_sample
84 .map(|s| s * self.channel_volumes[self.current_channel]);
85 self.current_channel += 1;
86 result
87 }
88
89 #[inline]
90 fn size_hint(&self) -> (usize, Option<usize>) {
91 self.input.size_hint()
92 }
93}
94
95impl<I> ExactSizeIterator for ChannelVolume<I> where I: Source + ExactSizeIterator {}
96
97impl<I> Source for ChannelVolume<I>
98where
99 I: Source,
100{
101 #[inline]
102 fn current_span_len(&self) -> Option<usize> {
103 self.input.current_span_len()
104 }
105
106 #[inline]
107 fn channels(&self) -> ChannelCount {
108 ChannelCount::new(self.channel_volumes.len() as u16)
109 .expect("checked to be non-empty in new implementation")
110 }
111
112 #[inline]
113 fn sample_rate(&self) -> SampleRate {
114 self.input.sample_rate()
115 }
116
117 #[inline]
118 fn total_duration(&self) -> Option<Duration> {
119 self.input.total_duration()
120 }
121
122 #[inline]
123 fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
124 self.input.try_seek(pos)
125 }
126}