Add run time option flags for AlsaMixer

Add `Cargo.lock` for Travis
This commit is contained in:
ashthespy 2018-09-11 18:53:18 +02:00
parent 99106c5ae3
commit 0e1147077c
5 changed files with 90 additions and 34 deletions

29
Cargo.lock generated
View file

@ -49,10 +49,13 @@ dependencies = [
[[package]] [[package]]
name = "alsa" name = "alsa"
version = "0.0.1" version = "0.2.1"
source = "git+https://github.com/plietar/rust-alsa#8c63543fa0ccd971cf15f5675293d19febd6f79e" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -164,6 +167,11 @@ name = "bitflags"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.0.4" version = "1.0.4"
@ -824,7 +832,7 @@ dependencies = [
name = "librespot-playback" name = "librespot-playback"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)", "alsa 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cpal 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "cpal 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1006,6 +1014,17 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "nix"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.11.0" version = "0.11.0"
@ -2181,7 +2200,7 @@ dependencies = [
"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" "checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d"
"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100"
"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" "checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
"checksum alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)" = "<none>" "checksum alsa 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fd5a75e70d45a943d2a0a818277e71d6ff777e97358529d6b460d3d4c4d0745"
"checksum alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b0edcbbf9ef68f15ae1b620f722180b82a98b6f0628d30baa6b8d2a5abc87d58" "checksum alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b0edcbbf9ef68f15ae1b620f722180b82a98b6f0628d30baa6b8d2a5abc87d58"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94" "checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
@ -2196,6 +2215,7 @@ dependencies = [
"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" "checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
"checksum bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32866f4d103c4e438b1db1158aa1b1a80ee078e5d77a59a2f906fd62a577389c" "checksum bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32866f4d103c4e438b1db1158aa1b1a80ee078e5d77a59a2f906fd62a577389c"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" "checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d"
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
@ -2279,6 +2299,7 @@ dependencies = [
"checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151" "checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
"checksum nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b" "checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
"checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" "checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1"

View file

@ -1,22 +1,19 @@
use super::AudioFilter; use super::AudioFilter;
use super::Mixer; use super::{Mixer, MixerConfig};
use std::env;
use std::error::Error; use std::error::Error;
use alsa; use alsa;
#[derive(Clone)] #[derive(Clone)]
pub struct AlsaMixer { pub struct AlsaMixer {
card: String, config: MixerConfig,
mixer: String,
index: u32,
} }
impl AlsaMixer { impl AlsaMixer {
fn map_volume(&self, set_volume:Option<u16>) -> Result<(u16),Box<Error>> { fn map_volume(&self, set_volume:Option<u16>) -> Result<(u16),Box<Error>> {
let mixer = alsa::mixer::Mixer::new(&self.card, false)?; let mixer = alsa::mixer::Mixer::new(&self.config.card, false)?;
let sid = alsa::mixer::SelemId::new(&*self.mixer, self.index); let sid = alsa::mixer::SelemId::new(&*self.config.mixer, self.config.index);
let selem = mixer.find_selem(&sid).expect("Coundn't find SelemId"); let selem = mixer.find_selem(&sid).expect("Coundn't find SelemId");
let (min, max) = selem.get_playback_volume_range(); let (min, max) = selem.get_playback_volume_range();
@ -41,19 +38,13 @@ impl AlsaMixer {
} }
impl Mixer for AlsaMixer { impl Mixer for AlsaMixer {
fn open(device: Option<String>) -> AlsaMixer { fn open(config: Option<MixerConfig>) -> AlsaMixer {
let card = env::var("LIBRESPOT_CARD").unwrap_or(device.unwrap_or(String::from("default"))); let config = config.unwrap_or_default();
let mixer = env::var("LIBRESPOT_MIXER").unwrap_or(String::from("PCM"));
let index: u32 = 0;
info!( info!(
"Setting up new mixer: card:{} mixer:{} index:{}", "Setting up new mixer: card:{} mixer:{} index:{}",
card, mixer, index config.card, config.mixer, config.index
); );
AlsaMixer { AlsaMixer { config: config }
card: card,
mixer: mixer,
index: index,
}
} }
fn start(&self) { fn start(&self) {
@ -67,7 +58,7 @@ impl Mixer for AlsaMixer {
match self.map_volume(None){ match self.map_volume(None){
Ok(vol) => vol, Ok(vol) => vol,
Err(e) => { Err(e) => {
error!("Error getting volume for <{}>, {:?}",self.card, e); error!("Error getting volume for <{}>, {:?}",self.config.card, e);
0 } 0 }
} }
} }
@ -75,7 +66,7 @@ impl Mixer for AlsaMixer {
fn set_volume(&self, volume: u16) { fn set_volume(&self, volume: u16) {
match self.map_volume(Some(volume)){ match self.map_volume(Some(volume)){
Ok(_) => (), Ok(_) => (),
Err(e) => error!("Error setting volume for <{}>, {:?}",self.card, e), Err(e) => error!("Error setting volume for <{}>, {:?}",self.config.card, e),
} }
} }

View file

@ -1,5 +1,5 @@
pub trait Mixer: Send { pub trait Mixer: Send {
fn open(Option<String>) -> Self fn open(Option<MixerConfig>) -> Self
where where
Self: Sized; Self: Sized;
fn start(&self); fn start(&self);
@ -20,14 +20,30 @@ pub mod alsamixer;
#[cfg(feature = "alsa-backend")] #[cfg(feature = "alsa-backend")]
use self::alsamixer::AlsaMixer; use self::alsamixer::AlsaMixer;
#[derive(Debug, Clone)]
pub struct MixerConfig {
pub card: String,
pub mixer: String,
pub index: u32,
}
impl Default for MixerConfig {
fn default() -> MixerConfig { MixerConfig {
card: String::from("default"),
mixer: String::from("PCM"),
index: 0,
}
}
}
pub mod softmixer; pub mod softmixer;
use self::softmixer::SoftMixer; use self::softmixer::SoftMixer;
fn mk_sink<M: Mixer + 'static>(device: Option<String>) -> Box<Mixer> { fn mk_sink<M: Mixer + 'static>(device: Option<MixerConfig>) -> Box<Mixer> {
Box::new(M::open(device)) Box::new(M::open(device))
} }
pub fn find<T: AsRef<str>>(name: Option<T>) -> Option<fn(Option<String>) -> Box<Mixer>> { pub fn find<T: AsRef<str>>(name: Option<T>) -> Option<fn(Option<MixerConfig>) -> Box<Mixer>> {
match name.as_ref().map(AsRef::as_ref) { match name.as_ref().map(AsRef::as_ref) {
None | Some("softvol") => Some(mk_sink::<SoftMixer>), None | Some("softvol") => Some(mk_sink::<SoftMixer>),
#[cfg(feature = "alsa-backend")] #[cfg(feature = "alsa-backend")]

View file

@ -2,7 +2,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc; use std::sync::Arc;
use super::AudioFilter; use super::AudioFilter;
use super::Mixer; use super::{Mixer, MixerConfig};
#[derive(Clone)] #[derive(Clone)]
pub struct SoftMixer { pub struct SoftMixer {
@ -10,7 +10,7 @@ pub struct SoftMixer {
} }
impl Mixer for SoftMixer { impl Mixer for SoftMixer {
fn open(_: Option<String>) -> SoftMixer { fn open(_: Option<MixerConfig>) -> SoftMixer {
SoftMixer { SoftMixer {
volume: Arc::new(AtomicUsize::new(0xFFFF)), volume: Arc::new(AtomicUsize::new(0xFFFF)),
} }

View file

@ -37,7 +37,7 @@ use librespot::connect::discovery::{discovery, DiscoveryStream};
use librespot::connect::spirc::{Spirc, SpircTask}; use librespot::connect::spirc::{Spirc, SpircTask};
use librespot::playback::audio_backend::{self, Sink, BACKENDS}; use librespot::playback::audio_backend::{self, Sink, BACKENDS};
use librespot::playback::config::{Bitrate, PlayerConfig}; use librespot::playback::config::{Bitrate, PlayerConfig};
use librespot::playback::mixer::{self, Mixer}; use librespot::playback::mixer::{self, Mixer, MixerConfig};
use librespot::playback::player::{Player, PlayerEvent}; use librespot::playback::player::{Player, PlayerEvent};
mod player_event_handler; mod player_event_handler;
@ -90,12 +90,13 @@ struct Setup {
backend: fn(Option<String>) -> Box<Sink>, backend: fn(Option<String>) -> Box<Sink>,
device: Option<String>, device: Option<String>,
mixer: fn(Option<String>) -> Box<Mixer>, mixer: fn(Option<MixerConfig>) -> Box<Mixer>,
cache: Option<Cache>, cache: Option<Cache>,
player_config: PlayerConfig, player_config: PlayerConfig,
session_config: SessionConfig, session_config: SessionConfig,
connect_config: ConnectConfig, connect_config: ConnectConfig,
mixer_config: MixerConfig,
credentials: Option<Credentials>, credentials: Option<Credentials>,
enable_discovery: bool, enable_discovery: bool,
zeroconf_port: u16, zeroconf_port: u16,
@ -142,7 +143,25 @@ fn setup(args: &[String]) -> Setup {
"Audio device to use. Use '?' to list options if using portaudio", "Audio device to use. Use '?' to list options if using portaudio",
"DEVICE", "DEVICE",
) )
.optopt("", "mixer", "Mixer to use", "MIXER") .optopt("", "mixer", "Mixer to use (Alsa or softmixer)", "MIXER")
.optopt(
"m",
"mixer-name",
"Alsa mixer name, e.g \"PCM\" or \"Master\". Defaults to 'PCM'",
"MIXER_NAME",
)
.optopt(
"",
"mixer-card",
"Alsa mixer card, e.g \"hw:0\" or similar from `aplay -l`. Defaults to 'default' ",
"MIXER_CARD",
)
.optopt(
"",
"mixer-index",
"Alsa mixer index, Index of the cards mixer. Defaults to 0",
"MIXER_INDEX",
)
.optopt( .optopt(
"", "",
"initial-volume", "initial-volume",
@ -208,6 +227,12 @@ fn setup(args: &[String]) -> Setup {
let mixer_name = matches.opt_str("mixer"); let mixer_name = matches.opt_str("mixer");
let mixer = mixer::find(mixer_name.as_ref()).expect("Invalid mixer"); let mixer = mixer::find(mixer_name.as_ref()).expect("Invalid mixer");
let mixer_config = MixerConfig {
card: matches.opt_str("mixer-card").unwrap_or(String::from("default")),
mixer: matches.opt_str("mixer-name").unwrap_or(String::from("PCM")),
index: matches.opt_str("mixer-index").map(|index| index.parse::<u32>().unwrap()).unwrap_or(0),
};
let use_audio_cache = !matches.opt_present("disable-audio-cache"); let use_audio_cache = !matches.opt_present("disable-audio-cache");
let cache = matches let cache = matches
@ -324,6 +349,7 @@ fn setup(args: &[String]) -> Setup {
enable_discovery: enable_discovery, enable_discovery: enable_discovery,
zeroconf_port: zeroconf_port, zeroconf_port: zeroconf_port,
mixer: mixer, mixer: mixer,
mixer_config: mixer_config,
player_event_program: matches.opt_str("onevent"), player_event_program: matches.opt_str("onevent"),
} }
} }
@ -335,7 +361,8 @@ struct Main {
connect_config: ConnectConfig, connect_config: ConnectConfig,
backend: fn(Option<String>) -> Box<Sink>, backend: fn(Option<String>) -> Box<Sink>,
device: Option<String>, device: Option<String>,
mixer: fn(Option<String>) -> Box<Mixer>, mixer: fn(Option<MixerConfig>) -> Box<Mixer>,
mixer_config: MixerConfig,
handle: Handle, handle: Handle,
discovery: Option<DiscoveryStream>, discovery: Option<DiscoveryStream>,
@ -362,6 +389,7 @@ impl Main {
backend: setup.backend, backend: setup.backend,
device: setup.device, device: setup.device,
mixer: setup.mixer, mixer: setup.mixer,
mixer_config: setup.mixer_config,
connect: Box::new(futures::future::empty()), connect: Box::new(futures::future::empty()),
discovery: None, discovery: None,
@ -422,8 +450,8 @@ impl Future for Main {
if let Async::Ready(session) = self.connect.poll().unwrap() { if let Async::Ready(session) = self.connect.poll().unwrap() {
self.connect = Box::new(futures::future::empty()); self.connect = Box::new(futures::future::empty());
let device = self.device.clone(); let mixer_config = self.mixer_config.clone();
let mixer = (self.mixer)(device); let mixer = (self.mixer)(Some(mixer_config));
let player_config = self.player_config.clone(); let player_config = self.player_config.clone();
let connect_config = self.connect_config.clone(); let connect_config = self.connect_config.clone();