2018-03-20 15:32:43 +00:00
|
|
|
use super::Mixer;
|
|
|
|
use super::AudioFilter;
|
|
|
|
|
|
|
|
use alsa;
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct AlsaMixer {
|
2018-03-21 21:18:37 +00:00
|
|
|
card: String,
|
|
|
|
mixer: String,
|
2018-03-20 15:32:43 +00:00
|
|
|
}
|
|
|
|
|
2018-03-21 21:18:37 +00:00
|
|
|
// Doesn't work - Selem is borrowed from Mixer
|
|
|
|
// impl AlsaMixer {
|
|
|
|
// fn get_selem(&self ) -> Result<(alsa::mixer::Selem), Box<Error>> {
|
|
|
|
//
|
|
|
|
// let selem_id = alsa::mixer::SelemId::new(self.mixer, 0);
|
|
|
|
// let mixer = alsa::mixer::Mixer::new(self.card, false)?;
|
|
|
|
// let selem = mixer.find_selem(&selem_id).unwrap();
|
|
|
|
//
|
|
|
|
// Ok((selem))
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
2018-03-20 15:32:43 +00:00
|
|
|
impl Mixer for AlsaMixer {
|
|
|
|
fn open(device: Option<String>) -> AlsaMixer {
|
2018-03-21 21:18:37 +00:00
|
|
|
let card = device.unwrap_or(String::from("default"));
|
|
|
|
let mixer = String::from("PCM");
|
2018-03-20 15:32:43 +00:00
|
|
|
AlsaMixer {
|
2018-03-21 21:18:37 +00:00
|
|
|
card: card,
|
|
|
|
mixer: mixer,
|
2018-03-20 15:32:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn start(&self) {
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stop(&self) {
|
|
|
|
}
|
|
|
|
|
|
|
|
fn volume(&self) -> u16 {
|
2018-03-21 21:18:37 +00:00
|
|
|
let mixer = alsa::mixer::Mixer::new(&self.card, false).unwrap();
|
|
|
|
let selem_id = alsa::mixer::SelemId::new(&self.mixer, 0);
|
2018-03-20 15:32:43 +00:00
|
|
|
let selem = mixer.find_selem(&selem_id).unwrap();
|
|
|
|
let (min, max) = selem.get_playback_volume_range();
|
|
|
|
let volume: i64 = selem.get_playback_volume(alsa::mixer::SelemChannelId::FrontLeft).unwrap();
|
|
|
|
|
|
|
|
// Spotify uses a volume range from 0 to 65535, but the ALSA mixers resolution might
|
|
|
|
// differ, e.g. most ALSA mixers uses a resolution of 256. Therefore, we have to calculate
|
|
|
|
// the multiplier to use, to get the corresponding Spotify volume value from the ALSA
|
|
|
|
// mixers volume.
|
|
|
|
let resolution = max - min + 1;
|
|
|
|
let multiplier: u16 = (((0xFFFF + 1) / resolution) - 1) as u16;
|
|
|
|
|
|
|
|
volume as u16 * multiplier
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_volume(&self, volume: u16) {
|
2018-03-21 21:18:37 +00:00
|
|
|
let mixer = alsa::mixer::Mixer::new(&self.card, false).unwrap();
|
|
|
|
let selem_id = alsa::mixer::SelemId::new(&self.mixer, 0);
|
2018-03-20 15:32:43 +00:00
|
|
|
let selem = mixer.find_selem(&selem_id).unwrap();
|
|
|
|
let (min, max) = selem.get_playback_volume_range();
|
|
|
|
|
|
|
|
// Spotify uses a volume range from 0 to 65535, but the ALSA mixers resolution might
|
|
|
|
// differ, e.g. most ALSA mixers uses a resolution of 256. Therefore, we have to calculate
|
|
|
|
// the factor to use, to get the corresponding ALSA mixers volume value from the Spotify
|
|
|
|
// volume.
|
|
|
|
let resolution = max - min + 1;
|
|
|
|
let factor: u16 = (((0xFFFF + 1) / resolution) - 1) as u16;
|
|
|
|
let volume: i64 = (volume / factor) as i64;
|
2018-03-21 21:18:37 +00:00
|
|
|
info!("Setting volume: {:?}", volume);
|
2018-03-20 15:32:43 +00:00
|
|
|
selem.set_playback_volume_all(volume).unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_audio_filter(&self) -> Option<Box<AudioFilter + Send>> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|