softmixer.rs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. use std::borrow::Cow;
  2. use std::sync::{Arc, RwLock};
  3. use spirc::UpdateMessageSender;
  4. use spirc::UpdateMessage;
  5. use super::Mixer;
  6. use super::AudioFilter;
  7. pub struct SoftMixer {
  8. volume: Arc<RwLock<u16>>,
  9. tx: Option<UpdateMessageSender>
  10. }
  11. impl SoftMixer {
  12. pub fn new() -> SoftMixer {
  13. SoftMixer {
  14. volume: Arc::new(RwLock::new(0xFFFF)),
  15. tx: None
  16. }
  17. }
  18. }
  19. impl Mixer for SoftMixer {
  20. fn init(&mut self, tx: UpdateMessageSender) {
  21. self.tx = Some(tx);
  22. }
  23. fn start(&self) {
  24. }
  25. fn stop(&self) {
  26. }
  27. fn volume(&self) -> u16 {
  28. *self.volume.read().unwrap()
  29. }
  30. fn set_volume(&self, volume: u16) {
  31. *self.volume.write().unwrap() = volume;
  32. let tx = self.tx.as_ref().expect("SoftMixer not initialized");
  33. tx.send(UpdateMessage).unwrap();
  34. }
  35. fn get_audio_filter(&self) -> Option<Box<AudioFilter + Send>> {
  36. let vol = self.volume.clone();
  37. let get_volume = Box::new(move || *vol.read().unwrap());
  38. Some(Box::new(SoftVolumeApplier { get_volume: get_volume }))
  39. }
  40. }
  41. struct SoftVolumeApplier {
  42. get_volume: Box<Fn() -> u16 + Send>
  43. }
  44. impl AudioFilter for SoftVolumeApplier {
  45. fn modify_stream<'a>(&self, data: &'a [i16]) -> Cow<'a, [i16]> {
  46. let volume = (self.get_volume)();
  47. if volume == 0xFFFF {
  48. Cow::Borrowed(data)
  49. } else {
  50. Cow::Owned(data.iter()
  51. .map(|&x| {
  52. (x as i32
  53. * volume as i32
  54. / 0xFFFF) as i16
  55. })
  56. .collect())
  57. }
  58. }
  59. }