diff --git a/src/mixer/mod.rs b/src/mixer/mod.rs index 32350af3..3c7e6b75 100644 --- a/src/mixer/mod.rs +++ b/src/mixer/mod.rs @@ -1,7 +1,3 @@ -use self::softmixer::SoftMixer; - -pub mod softmixer; - pub trait Mixer { fn start(&self); fn stop(&self); @@ -13,11 +9,15 @@ pub trait Mixer { } pub trait AudioFilter { - fn modify_stream(&self, data: &mut [i16]); + fn modify_stream(&self, data: &mut [i16]); } +pub mod softmixer; +use self::softmixer::SoftMixer; + pub fn find>(name: Option) -> Option> { - match name { - _ => Some(Box::new(SoftMixer::new())), - } -} \ No newline at end of file + match name.as_ref().map(AsRef::as_ref) { + None | Some("softvol") => Some(Box::new(SoftMixer::new())), + _ => None, + } +} diff --git a/src/player.rs b/src/player.rs index aad23dfa..7d21a24e 100644 --- a/src/player.rs +++ b/src/player.rs @@ -72,8 +72,9 @@ enum PlayerCommand { } impl Player { - pub fn new(session: Session, stream_editor: Option>, sink_builder: F) -> Player - where F: FnOnce() -> Box + Send + 'static { + pub fn new(session: Session, audio_filter: Option>, sink_builder: F) -> Player + where F: FnOnce() -> Box + Send + 'static + { let (cmd_tx, cmd_rx) = mpsc::channel(); let state = Arc::new(Mutex::new(PlayerState { @@ -93,7 +94,7 @@ impl Player { observers: observers.clone(), }; - thread::spawn(move || internal.run(sink_builder(), stream_editor)); + thread::spawn(move || internal.run(sink_builder(), audio_filter)); Player { commands: cmd_tx, @@ -206,7 +207,7 @@ fn run_onstop(session: &Session) { } impl PlayerInternal { - fn run(self, mut sink: Box, stream_editor: Option>) { + fn run(self, mut sink: Box, audio_filter: Option>) { let mut decoder = None; loop { @@ -341,7 +342,7 @@ impl PlayerInternal { match packet { Some(Ok(mut packet)) => { - if let Some(ref editor) = stream_editor { + if let Some(ref editor) = audio_filter { editor.modify_stream(&mut packet.data) }; sink.write(&packet.data).unwrap(); diff --git a/src/spirc.rs b/src/spirc.rs index c532f794..36be37c7 100644 --- a/src/spirc.rs +++ b/src/spirc.rs @@ -44,53 +44,6 @@ struct SpircInternal { devices: HashMap, } -#[derive(Clone)] -pub struct State { - pub status: PlayStatus, - pub position_ms: u32, - pub position_measured_at: i64, - pub update_time: i64, - pub volume: u16, - pub track: Option, - pub end_of_track: bool, -} - -impl State { - pub fn new() -> State { - let state = State { - status: PlayStatus::kPlayStatusStop, - position_ms: 0, - position_measured_at: 0, - update_time: 0, - volume: 0, - track: None, - end_of_track: false, - }; - state.update_time() - } - - pub fn update_from_player(mut self, player: &Player) -> State { - let player_state = player.state(); - let (position_ms, position_measured_at) = player_state.position(); - self.status = player_state.status(); - self.position_ms = position_ms; - self.position_measured_at = position_measured_at; - self.track = player_state.track; - self.end_of_track = player_state.end_of_track(); - self.update_time() - } - - pub fn update_from_mixer(mut self, mixer: &Box) -> State { - self.volume = mixer.volume(); - self.update_time() - } - - fn update_time(mut self) -> State { - self.update_time = util::now_ms(); - self - } -} - impl SpircManager { pub fn new(session: Session, player: Player, mixer: Box) -> SpircManager { let ident = session.device_id().to_owned(); @@ -340,11 +293,14 @@ impl SpircInternal { cs.send(); } - fn spirc_state(&self, state: &State) -> protocol::spirc::State { + fn spirc_state(&self) -> protocol::spirc::State { + let player_state = self.player.state(); + let (position_ms, position_measured_at) = player_state.position(); + protobuf_init!(protocol::spirc::State::new(), { - status: state.status, - position_ms: state.position_ms, - position_measured_at: state.position_measured_at as u64, + status: player_state.status(), + position_ms: position_ms, + position_measured_at: position_measured_at as u64, playing_track_index: self.index, track: self.tracks.iter().map(|track| { @@ -363,12 +319,12 @@ impl SpircInternal { }) } - fn device_state(&self, state: &State) -> protocol::spirc::DeviceState { + fn device_state(&self) -> protocol::spirc::DeviceState { protobuf_init!(protocol::spirc::DeviceState::new(), { sw_version: version::version_string(), is_active: self.is_active, can_play: self.can_play, - volume: state.volume as u32, + volume: self.mixer.volume() as u32, name: self.name.clone(), error_code: 0, became_active_at: if self.is_active { self.became_active_at as i64 } else { 0 }, @@ -429,63 +385,54 @@ impl SpircInternal { } struct CommandSender<'a> { - spirc_internal: &'a mut SpircInternal, - cmd: MessageType, - recipient: Option<&'a str>, - state: Option, + spirc: &'a mut SpircInternal, + frame: protocol::spirc::Frame, } impl<'a> CommandSender<'a> { - fn new(spirc_internal: &'a mut SpircInternal, cmd: MessageType) -> CommandSender { - CommandSender { - spirc_internal: spirc_internal, - cmd: cmd, - recipient: None, - state: None, - } - } - - fn recipient(mut self, r: &'a str) -> CommandSender { - self.recipient = Some(r); - self - } - - fn state(mut self, s: protocol::spirc::State) -> CommandSender<'a> { - self.state = Some(s); - self - } - - fn send(self) { - let state = State::new() - .update_from_player(&self.spirc_internal.player) - .update_from_mixer(&self.spirc_internal.mixer); - - let mut pkt = protobuf_init!(protocol::spirc::Frame::new(), { + fn new(spirc: &'a mut SpircInternal, cmd: MessageType) -> CommandSender { + let frame = protobuf_init!(protocol::spirc::Frame::new(), { version: 1, - ident: self.spirc_internal.ident.clone(), protocol_version: "2.0.0", - seq_nr: { self.spirc_internal.seq_nr += 1; self.spirc_internal.seq_nr }, - typ: self.cmd, - recipient: RepeatedField::from_vec( - self.recipient.map(|r| vec![r.to_owned()] ).unwrap_or(vec![]) - ), - device_state: self.spirc_internal.device_state(&state), - state_update_id: state.update_time + ident: spirc.ident.clone(), + seq_nr: { spirc.seq_nr += 1; spirc.seq_nr }, + typ: cmd, + + device_state: spirc.device_state(), + state_update_id: util::now_ms(), }); - if self.spirc_internal.is_active { - pkt.set_state(self.spirc_internal.spirc_state(&state)); + CommandSender { + spirc: spirc, + frame: frame, + } + } + + fn recipient(mut self, recipient: &'a str) -> CommandSender { + self.frame.mut_recipient().push(recipient.to_owned()); + self + } + + fn state(mut self, state: protocol::spirc::State) -> CommandSender<'a> { + self.frame.set_state(state); + self + } + + fn send(mut self) { + if !self.frame.has_state() && self.spirc.is_active { + self.frame.set_state(self.spirc.spirc_state()); } - self.spirc_internal + let payload = vec![self.frame.write_to_bytes().unwrap()]; + + self.spirc .session .mercury(MercuryRequest { method: MercuryMethod::SEND, - uri: self.spirc_internal.uri(), + uri: self.spirc.uri(), content_type: None, - payload: vec![pkt.write_to_bytes().unwrap()], - }) - .fire(); + payload: payload, + }).fire(); } }