Paul Lietar vor 7 Jahren
Ursprung
Commit
5974cf7f24
3 geänderte Dateien mit 53 neuen und 105 gelöschten Zeilen
  1. 9 9
      src/mixer/mod.rs
  2. 6 5
      src/player.rs
  3. 38 91
      src/spirc.rs

+ 9 - 9
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<T: AsRef<str>>(name: Option<T>) -> Option<Box<Mixer + Send>> {
-  match name {
-    _ => Some(Box::new(SoftMixer::new())),
-  }
-}
+    match name.as_ref().map(AsRef::as_ref) {
+        None | Some("softvol") => Some(Box::new(SoftMixer::new())),
+        _ => None,
+    }
+}

+ 6 - 5
src/player.rs

@@ -72,8 +72,9 @@ enum PlayerCommand {
 }
 
 impl Player {
-    pub fn new<F>(session: Session, stream_editor: Option<Box<AudioFilter + Send>>, sink_builder: F) -> Player
-        where F: FnOnce() -> Box<Sink> + Send + 'static {
+    pub fn new<F>(session: Session, audio_filter: Option<Box<AudioFilter + Send>>, sink_builder: F) -> Player
+        where F: FnOnce() -> Box<Sink> + 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<Sink>, stream_editor: Option<Box<AudioFilter + Send>>) {
+    fn run(self, mut sink: Box<Sink>, audio_filter: Option<Box<AudioFilter + Send>>) {
         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();

+ 38 - 91
src/spirc.rs

@@ -44,53 +44,6 @@ struct SpircInternal {
     devices: HashMap<String, String>,
 }
 
-#[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<SpotifyId>,
-    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<Mixer + Send>) -> 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<Mixer + Send>) -> 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<protocol::spirc::State>,
+    spirc: &'a mut SpircInternal,
+    frame: protocol::spirc::Frame,
 }
 
 impl<'a> CommandSender<'a> {
-    fn new(spirc_internal: &'a mut SpircInternal, cmd: MessageType) -> CommandSender {
+    fn new(spirc: &'a mut SpircInternal, cmd: MessageType) -> CommandSender {
+        let frame = protobuf_init!(protocol::spirc::Frame::new(), {
+            version: 1,
+            protocol_version: "2.0.0",
+            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(),
+        });
+
         CommandSender {
-            spirc_internal: spirc_internal,
-            cmd: cmd,
-            recipient: None,
-            state: None,
+            spirc: spirc,
+            frame: frame,
         }
     }
 
-    fn recipient(mut self, r: &'a str) -> CommandSender {
-        self.recipient = Some(r);
+    fn recipient(mut self, recipient: &'a str) -> CommandSender {
+        self.frame.mut_recipient().push(recipient.to_owned());
         self
     }
 
-    fn state(mut self, s: protocol::spirc::State) -> CommandSender<'a> {
-        self.state = Some(s);
+    fn state(mut self, state: protocol::spirc::State) -> CommandSender<'a> {
+        self.frame.set_state(state);
         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(), {
-            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
-        });
-
-        if self.spirc_internal.is_active {
-            pkt.set_state(self.spirc_internal.spirc_state(&state));
+    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();
     }
 }