فهرست منبع

Remove mixer from Player and add it to SpircManager

Daniel Romero 8 سال پیش
والد
کامیت
59398b3cee
5فایلهای تغییر یافته به همراه48 افزوده شده و 80 حذف شده
  1. 7 5
      src/main.rs
  2. 1 1
      src/mixer/mod.rs
  3. 1 1
      src/mixer/softmixer.rs
  4. 6 33
      src/player.rs
  5. 33 40
      src/spirc.rs

+ 7 - 5
src/main.rs

@@ -19,6 +19,8 @@ use librespot::cache::{Cache, DefaultCache, NoCache};
 use librespot::player::Player;
 use librespot::session::{Bitrate, Config, Session};
 use librespot::mixer::softmixer::SoftMixer;
+use librespot::mixer::Mixer;
+
 use librespot::version;
 
 fn usage(program: &str, opts: &getopts::Options) -> String {
@@ -60,7 +62,7 @@ fn list_backends() {
     }
 }
 
-fn setup(args: &[String]) -> (Session, Player) {
+fn setup(args: &[String]) -> (Session, Player, Box<Mixer + Send>) {
     let mut opts = getopts::Options::new();
     opts.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE")
         .reqopt("n", "name", "Device name", "NAME")
@@ -124,18 +126,18 @@ fn setup(args: &[String]) -> (Session, Player) {
     let mixer = SoftMixer::new();
 
     let device_name = matches.opt_str("device");
-    let player = Player::new(session.clone(), Box::new(mixer), move || {
+    let player = Player::new(session.clone(), move || {
         (backend)(device_name.as_ref().map(AsRef::as_ref))
     });
 
-    (session, player)
+    (session, player, Box::new(mixer))
 }
 
 fn main() {
     let args: Vec<String> = std::env::args().collect();
-    let (session, player) = setup(&args);
+    let (session, player, mixer) = setup(&args);
 
-    let spirc = SpircManager::new(session.clone(), player);
+    let spirc = SpircManager::new(session.clone(), player, mixer);
     let spirc_signal = spirc.clone();
     thread::spawn(move || spirc.run());
 

+ 1 - 1
src/mixer/mod.rs

@@ -6,7 +6,7 @@ pub trait Mixer {
     fn init(&mut self);
     fn inuse(&mut self);
     fn release(&mut self);
-    fn set(&mut self, volume: u16);
+    fn set_volume(&mut self, volume: u16);
     fn volume(&self) -> u16;
     fn apply_volume<'a>(&mut self, data: &'a [i16]) -> Cow<'a, [i16]> {
         Cow::Borrowed(data)

+ 1 - 1
src/mixer/softmixer.rs

@@ -23,7 +23,7 @@ impl Mixer for SoftMixer {
     fn release(&mut self) {
     }
 
-    fn set(&mut self, volume: u16) {
+    fn set_volume(&mut self, volume: u16) {
         self.volume = volume;
     }
 

+ 6 - 33
src/player.rs

@@ -7,7 +7,6 @@ use vorbis;
 
 use audio_decrypt::AudioDecrypt;
 use audio_backend::Sink;
-use mixer::Mixer;
 use metadata::{FileFormat, Track, TrackRef};
 use session::{Bitrate, Session};
 use util::{self, ReadSeek, SpotifyId, Subfile};
@@ -48,8 +47,6 @@ pub struct PlayerState {
     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,
@@ -68,24 +65,20 @@ enum PlayerCommand {
     Load(SpotifyId, bool, u32),
     Play,
     Pause,
-    Volume(u16),
     Stop,
     Seek(u32),
     SeekAt(u32, i64),
 }
 
 impl Player {
-    pub fn new<F, M>(session: Session, mixer: Box<M>, sink_builder: F) -> Player
-        where F: FnOnce() -> Box<Sink> + Send + 'static,
-              M: Mixer + Send + 'static {
+    pub fn new<F>(session: Session, 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 {
             status: PlayStatus::kPlayStatusStop,
             position_ms: 0,
             position_measured_at: 0,
-            update_time: util::now_ms(),
-            volume: mixer.volume(),
             track: None,
             end_of_track: false,
         }));
@@ -99,7 +92,7 @@ impl Player {
             observers: observers.clone(),
         };
 
-        thread::spawn(move || internal.run(sink_builder(), mixer));
+        thread::spawn(move || internal.run(sink_builder()));
 
         Player {
             commands: cmd_tx,
@@ -140,10 +133,6 @@ impl Player {
         self.state.lock().unwrap().clone()
     }
 
-    pub fn volume(&self, vol: u16) {
-        self.command(PlayerCommand::Volume(vol));
-    }
-
     pub fn add_observer(&self, observer: PlayerObserver) {
         self.observers.lock().unwrap().push(observer);
     }
@@ -216,7 +205,7 @@ fn run_onstop(session: &Session) {
 }
 
 impl PlayerInternal {
-    fn run(self, mut sink: Box<Sink>, mut mixer: Box<Mixer>) {
+    fn run(self, mut sink: Box<Sink>) {
         let mut decoder = None;
 
         loop {
@@ -321,7 +310,6 @@ impl PlayerInternal {
                 Some(PlayerCommand::Pause) => {
                     self.update(|state| {
                         state.status = PlayStatus::kPlayStatusPause;
-                        state.update_time = util::now_ms();
                         state.position_ms = decoder.as_mut().map(|d| vorbis_time_tell_ms(d).unwrap()).unwrap_or(0) as u32;
                         state.position_measured_at = util::now_ms();
                         true
@@ -330,13 +318,6 @@ impl PlayerInternal {
                     sink.stop().unwrap();
                     run_onstop(&self.session);
                 }
-                Some(PlayerCommand::Volume(vol)) => {
-                    mixer.set(vol);
-                    self.update(|state| {
-                        state.volume = mixer.volume();
-                        true
-                    });
-                }
                 Some(PlayerCommand::Stop) => {
                     self.update(|state| {
                         if state.status == PlayStatus::kPlayStatusPlay {
@@ -359,7 +340,8 @@ impl PlayerInternal {
 
                 match packet {
                     Some(Ok(packet)) => {
-                        let buffer = mixer.apply_volume(&packet.data);
+                        //let buffer = mixer.apply_volume(&packet.data);
+                        let buffer = Cow::Borrowed(&packet.data);
                         sink.write(&buffer).unwrap();
 
                         self.update(|state| {
@@ -395,7 +377,6 @@ impl PlayerInternal {
 
         let observers = self.observers.lock().unwrap();
         if update {
-            guard.update_time = util::now_ms();
             let state = guard.clone();
             drop(guard);
 
@@ -415,14 +396,6 @@ impl PlayerState {
         (self.position_ms, self.position_measured_at)
     }
 
-    pub fn volume(&self) -> u16 {
-        self.volume
-    }
-
-    pub fn update_time(&self) -> i64 {
-        self.update_time
-    }
-
     pub fn end_of_track(&self) -> bool {
         self.end_of_track
     }

+ 33 - 40
src/spirc.rs

@@ -6,6 +6,7 @@ use std::collections::HashMap;
 
 use mercury::{MercuryRequest, MercuryMethod};
 use player::{Player, PlayerState};
+use mixer::Mixer;
 use session::Session;
 use util;
 use util::SpotifyId;
@@ -20,6 +21,7 @@ pub struct SpircManager(Arc<Mutex<SpircInternal>>);
 struct SpircInternal {
     player: Player,
     session: Session,
+    mixer: Box<Mixer + Send>,
 
     seq_nr: u32,
 
@@ -43,14 +45,26 @@ 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 SpircManager {
-    pub fn new(session: Session, player: Player) -> SpircManager {
+    pub fn new(session: Session, player: Player, mixer: Box<Mixer + Send>) -> SpircManager {
         let ident = session.device_id().to_owned();
         let name = session.config().device_name.clone();
 
         SpircManager(Arc::new(Mutex::new(SpircInternal {
             player: player,
             session: session,
+            mixer: mixer,
 
             seq_nr: 0,
 
@@ -184,7 +198,7 @@ impl SpircInternal {
             let track = self.tracks[self.index as usize];
             self.player.load(track, true, 0);
         } else {
-            self.notify_with_player_state(false, None, player_state);
+            self.notify(false, None);
         }
     }
 
@@ -253,7 +267,7 @@ impl SpircInternal {
                 }
             }
             MessageType::kMessageTypeVolume => {
-                self.player.volume(frame.get_volume() as u16);
+                self.mixer.set_volume(frame.get_volume() as u16);
             }
             MessageType::kMessageTypeGoodbye => {
                 if frame.has_ident() {
@@ -287,30 +301,11 @@ impl SpircInternal {
         cs.send();
     }
 
-    fn notify_with_player_state(&mut self,
-                                hello: bool,
-                                recipient: Option<&str>,
-                                player_state: &PlayerState) {
-        let mut cs = CommandSender::new(self,
-                                        if hello {
-                                            MessageType::kMessageTypeHello
-                                        } else {
-                                            MessageType::kMessageTypeNotify
-                                        })
-                         .player_state(player_state);
-        if let Some(s) = recipient {
-            cs = cs.recipient(&s);
-        }
-        cs.send();
-    }
-
-    fn spirc_state(&self, player_state: &PlayerState) -> protocol::spirc::State {
-        let (position_ms, position_measured_at) = player_state.position();
-
+    fn spirc_state(&self, state: &State) -> protocol::spirc::State {
         protobuf_init!(protocol::spirc::State::new(), {
-            status: player_state.status(),
-            position_ms: position_ms,
-            position_measured_at: position_measured_at as u64,
+            status: state.status,
+            position_ms: state.position_ms,
+            position_measured_at: state.position_measured_at as u64,
 
             playing_track_index: self.index,
             track: self.tracks.iter().map(|track| {
@@ -329,12 +324,12 @@ impl SpircInternal {
         })
     }
 
-    fn device_state(&self, player_state: &PlayerState) -> protocol::spirc::DeviceState {
+    fn device_state(&self, state: &State) -> 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: player_state.volume() as u32,
+            volume: state.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 },
@@ -398,7 +393,6 @@ struct CommandSender<'a> {
     spirc_internal: &'a mut SpircInternal,
     cmd: MessageType,
     recipient: Option<&'a str>,
-    player_state: Option<&'a PlayerState>,
     state: Option<protocol::spirc::State>,
 }
 
@@ -408,7 +402,6 @@ impl<'a> CommandSender<'a> {
             spirc_internal: spirc_internal,
             cmd: cmd,
             recipient: None,
-            player_state: None,
             state: None,
         }
     }
@@ -418,21 +411,21 @@ impl<'a> CommandSender<'a> {
         self
     }
 
-    fn player_state(mut self, s: &'a PlayerState) -> CommandSender {
-        self.player_state = Some(s);
-        self
-    }
-
     fn state(mut self, s: protocol::spirc::State) -> CommandSender<'a> {
         self.state = Some(s);
         self
     }
 
     fn send(self) {
-        let state = self.player_state.map_or_else(|| {
-            Cow::Owned(self.spirc_internal.player.state())
-        }, |s| {
-            Cow::Borrowed(s)
+        //TODO: get data
+        let state = Cow::Owned(State {
+            status: PlayStatus::kPlayStatusStop,
+            position_ms: 0,
+            position_measured_at: 0,
+            update_time: util::now_ms(),
+            volume: 0,
+            track: None,
+            end_of_track: false,
         });
 
         let mut pkt = protobuf_init!(protocol::spirc::Frame::new(), {
@@ -445,7 +438,7 @@ impl<'a> CommandSender<'a> {
                 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()
+            state_update_id: state.update_time
         });
 
         if self.spirc_internal.is_active {