diff --git a/Cargo.lock b/Cargo.lock index b349c15..094c227 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -726,9 +726,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "sbz-switch" version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/mdonoughe/sbz-switch#a3cbf4dd5dc5db7c2bc7039708e57aa96ea63f9e" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", @@ -747,7 +748,7 @@ version = "0.1.0" dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sbz-switch 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sbz-switch 3.0.0 (git+https://github.com/mdonoughe/sbz-switch)", "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1441,7 +1442,7 @@ dependencies = [ "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" -"checksum sbz-switch 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf357828062980b494bf003e6a126a4881b07c4373a520851a4db70425968c32" +"checksum sbz-switch 3.0.0 (git+https://github.com/mdonoughe/sbz-switch)" = "" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" diff --git a/Cargo.toml b/Cargo.toml index da60357..32288a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ travis-ci = { repository = "mdonoughe/sbzdeck" } [dependencies] futures = "0.1.25" indexmap = "1.0" -sbz-switch = "3.0" +sbz-switch = { version = "3.0", git = "https://github.com/mdonoughe/sbz-switch" } serde = "1.0" serde_derive = "1.0" serde_json = "1.0" diff --git a/src/main.rs b/src/main.rs index e9dea9f..06bca50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ mod types; use crate::types::*; use futures::prelude::*; use futures::sync::mpsc; +use sb::ChangeEvent; use slog::{crit, debug, error, info, warn, Logger}; use std::collections::BTreeSet; use std::env; @@ -260,47 +261,59 @@ fn main() { let evt = evt.unwrap(); debug!(logger_events, "saw change: {:?}", evt); let mut state = state_events.lock().unwrap(); - if &evt.feature == "Device Control" && &evt.parameter == "SelectOutput" { - match Output::try_from(&evt.value) { - Some(output) => { - state.output = Some(output); - for context in state.contexts.iter() { - let logger_e = logger_events.clone(); - tokio::spawn( - state - .out - .clone() - .send(MessageOut::SetState { - context: context.to_owned(), - payload: StatePayload { - state: output.into(), - }, - }) - .map_err(move |e| { - error!(logger_e, "failed to queue message: {:?}", e) - }) - .map(|_| ()), + match evt { + ChangeEvent::SoundCore(ref evt) + if evt.feature == "Device Control" && evt.parameter == "SelectOutput" => + { + match Output::try_from(&evt.value) { + Some(output) => { + state.output = Some(output); + for context in state.contexts.iter() { + let logger_e = logger_events.clone(); + tokio::spawn( + state + .out + .clone() + .send(MessageOut::SetState { + context: context.to_owned(), + payload: StatePayload { + state: output.into(), + }, + }) + .map_err(move |e| { + error!(logger_e, "failed to queue message: {:?}", e) + }) + .map(|_| ()), + ); + } + } + None => { + warn!( + logger_events, + "output device changed to unrecognized value {:?}", evt.value ); + state.output = None; } } - None => { - warn!( - logger_events, - "output device changed to unrecognized value {:?}", evt.value - ); - state.output = None; + } + ChangeEvent::SoundCore(evt) => { + if let Some(output) = state.output { + // Why update the profile here if we update the profile again right + // before switching? If the user changes a setting and then + // manually switches outputs, we want to capture that setting for + // the next time the user switches back to the original output. + let feature = state.profiles[output] + .parameters + .entry(evt.feature) + .or_default(); + feature.insert(evt.parameter, evt.value); + } + } + ChangeEvent::Volume(volume) => { + if let Some(output) = state.output { + state.profiles[output].volume = Some(volume); } } - } else if let Some(output) = state.output { - // Why update the profile here if we update the profile again right - // before switching? If the user changes a setting and then - // manually switches outputs, we want to capture that setting for - // the next time the user switches back to the original output. - let feature = state.profiles[output] - .parameters - .entry(evt.feature) - .or_default(); - feature.insert(evt.parameter, evt.value); } Ok(()) }); diff --git a/src/sb.rs b/src/sb.rs index 3311dd5..9c1ff52 100644 --- a/src/sb.rs +++ b/src/sb.rs @@ -2,8 +2,9 @@ use crate::types::*; use futures::prelude::*; use futures::sync::{mpsc, oneshot}; use indexmap::{IndexMap, IndexSet}; +use sbz_switch::media::VolumeNotification; use sbz_switch::soundcore::{SoundCoreEvent, SoundCoreParamValue}; -use sbz_switch::{Configuration, EndpointConfiguration, Win32Error}; +use sbz_switch::{Configuration, EndpointConfiguration, SoundCoreOrVolumeEvent, Win32Error}; use slog::error; use slog::Logger; use std::{iter, thread}; @@ -74,7 +75,13 @@ pub fn apply_profile( } #[derive(Debug)] -pub struct ChangeEvent { +pub enum ChangeEvent { + SoundCore(SoundCoreChangeEvent), + Volume(f32), +} + +#[derive(Debug)] +pub struct SoundCoreChangeEvent { pub feature: String, pub parameter: String, pub value: SoundCoreParamValue, @@ -85,24 +92,30 @@ pub fn watch(logger: &Logger) -> Result { let (event_tx, event_rx) = mpsc::channel(64); start_tx.send(Ok(event_rx)).unwrap(); let mut event_tx = event_tx.wait(); for event in iterator { match event { - Ok(SoundCoreEvent::ParamChange { feature, parameter }) => { + Ok(SoundCoreOrVolumeEvent::SoundCore(SoundCoreEvent::ParamChange { + feature, + parameter, + })) => { let event = match parameter.get() { - Ok(value) => Ok(ChangeEvent { + Ok(value) => Ok(ChangeEvent::SoundCore(SoundCoreChangeEvent { feature: feature.description.to_owned(), parameter: parameter.description.to_owned(), value, - }), + })), Err(error) => Err(error), }; event_tx.send(event).unwrap(); } + Ok(SoundCoreOrVolumeEvent::Volume(VolumeNotification { + volume, .. + })) => event_tx.send(Ok(ChangeEvent::Volume(volume))).unwrap(), Ok(_) => {} Err(error) => event_tx.send(Err(error)).unwrap(), }