chatsounds/
channel_volume.rs1use std::{
2 f32,
3 sync::{Arc, Mutex},
4 time::Duration,
5};
6
7use rodio::{cpal::FromSample, mixer::Mixer, source::ChannelVolume, PlayError, Sink, Source};
8
9pub struct ChannelVolumeSink {
10 pub sink: Sink,
11 channel_volumes: Arc<Mutex<Vec<f32>>>,
12}
13
14impl ChannelVolumeSink {
15 pub fn connect_new(mixer: &Mixer, channel_volumes: Vec<f32>) -> Result<Self, PlayError> {
16 Ok(Self {
17 sink: Sink::connect_new(mixer),
18 channel_volumes: Arc::new(Mutex::new(channel_volumes)),
19 })
20 }
21
22 pub fn set_channel_volumes(&self, channel_volumes: Vec<f32>) {
23 *self.channel_volumes.lock().unwrap() = channel_volumes;
24 }
25
26 pub fn append<S>(&self, source: S)
27 where
28 S: Source + Send + 'static,
29 f32: FromSample<S::Item>,
30 {
31 let channel_volumes = self.channel_volumes.clone();
32 let source = ChannelVolume::new(source, self.channel_volumes.lock().unwrap().clone())
33 .periodic_access(Duration::from_millis(10), move |i| {
34 let channel_volumes = channel_volumes.lock().unwrap();
35 for (channel, volume) in channel_volumes.iter().enumerate() {
36 i.set_volume(channel, *volume);
37 }
38 });
39 self.sink.append(source);
40 }
41}