Fixes for PR #148

This commit is contained in:
Paul Lietar 2017-02-21 21:49:45 +00:00
parent 387c2598e0
commit 5974cf7f24
3 changed files with 59 additions and 111 deletions

View file

@ -1,7 +1,3 @@
use self::softmixer::SoftMixer;
pub mod softmixer;
pub trait Mixer { pub trait Mixer {
fn start(&self); fn start(&self);
fn stop(&self); fn stop(&self);
@ -16,8 +12,12 @@ 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>> { pub fn find<T: AsRef<str>>(name: Option<T>) -> Option<Box<Mixer + Send>> {
match name { match name.as_ref().map(AsRef::as_ref) {
_ => Some(Box::new(SoftMixer::new())), None | Some("softvol") => Some(Box::new(SoftMixer::new())),
_ => None,
} }
} }

View file

@ -72,8 +72,9 @@ enum PlayerCommand {
} }
impl Player { impl Player {
pub fn new<F>(session: Session, stream_editor: Option<Box<AudioFilter + Send>>, sink_builder: F) -> Player pub fn new<F>(session: Session, audio_filter: Option<Box<AudioFilter + Send>>, sink_builder: F) -> Player
where F: FnOnce() -> Box<Sink> + Send + 'static { where F: FnOnce() -> Box<Sink> + Send + 'static
{
let (cmd_tx, cmd_rx) = mpsc::channel(); let (cmd_tx, cmd_rx) = mpsc::channel();
let state = Arc::new(Mutex::new(PlayerState { let state = Arc::new(Mutex::new(PlayerState {
@ -93,7 +94,7 @@ impl Player {
observers: observers.clone(), observers: observers.clone(),
}; };
thread::spawn(move || internal.run(sink_builder(), stream_editor)); thread::spawn(move || internal.run(sink_builder(), audio_filter));
Player { Player {
commands: cmd_tx, commands: cmd_tx,
@ -206,7 +207,7 @@ fn run_onstop(session: &Session) {
} }
impl PlayerInternal { 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; let mut decoder = None;
loop { loop {
@ -341,7 +342,7 @@ impl PlayerInternal {
match packet { match packet {
Some(Ok(mut 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) editor.modify_stream(&mut packet.data)
}; };
sink.write(&packet.data).unwrap(); sink.write(&packet.data).unwrap();

View file

@ -44,53 +44,6 @@ struct SpircInternal {
devices: HashMap<String, String>, 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 { impl SpircManager {
pub fn new(session: Session, player: Player, mixer: Box<Mixer + Send>) -> SpircManager { pub fn new(session: Session, player: Player, mixer: Box<Mixer + Send>) -> SpircManager {
let ident = session.device_id().to_owned(); let ident = session.device_id().to_owned();
@ -340,11 +293,14 @@ impl SpircInternal {
cs.send(); 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(), { protobuf_init!(protocol::spirc::State::new(), {
status: state.status, status: player_state.status(),
position_ms: state.position_ms, position_ms: position_ms,
position_measured_at: state.position_measured_at as u64, position_measured_at: position_measured_at as u64,
playing_track_index: self.index, playing_track_index: self.index,
track: self.tracks.iter().map(|track| { 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(), { protobuf_init!(protocol::spirc::DeviceState::new(), {
sw_version: version::version_string(), sw_version: version::version_string(),
is_active: self.is_active, is_active: self.is_active,
can_play: self.can_play, can_play: self.can_play,
volume: state.volume as u32, volume: self.mixer.volume() as u32,
name: self.name.clone(), name: self.name.clone(),
error_code: 0, error_code: 0,
became_active_at: if self.is_active { self.became_active_at as i64 } else { 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> { struct CommandSender<'a> {
spirc_internal: &'a mut SpircInternal, spirc: &'a mut SpircInternal,
cmd: MessageType, frame: protocol::spirc::Frame,
recipient: Option<&'a str>,
state: Option<protocol::spirc::State>,
} }
impl<'a> CommandSender<'a> { impl<'a> CommandSender<'a> {
fn new(spirc_internal: &'a mut SpircInternal, cmd: MessageType) -> CommandSender { fn new(spirc: &'a mut SpircInternal, cmd: MessageType) -> CommandSender {
CommandSender { let frame = protobuf_init!(protocol::spirc::Frame::new(), {
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(), {
version: 1, version: 1,
ident: self.spirc_internal.ident.clone(),
protocol_version: "2.0.0", protocol_version: "2.0.0",
seq_nr: { self.spirc_internal.seq_nr += 1; self.spirc_internal.seq_nr }, ident: spirc.ident.clone(),
typ: self.cmd, seq_nr: { spirc.seq_nr += 1; spirc.seq_nr },
recipient: RepeatedField::from_vec( typ: cmd,
self.recipient.map(|r| vec![r.to_owned()] ).unwrap_or(vec![])
), device_state: spirc.device_state(),
device_state: self.spirc_internal.device_state(&state), state_update_id: util::now_ms(),
state_update_id: state.update_time
}); });
if self.spirc_internal.is_active { CommandSender {
pkt.set_state(self.spirc_internal.spirc_state(&state)); spirc: spirc,
frame: frame,
}
} }
self.spirc_internal 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());
}
let payload = vec![self.frame.write_to_bytes().unwrap()];
self.spirc
.session .session
.mercury(MercuryRequest { .mercury(MercuryRequest {
method: MercuryMethod::SEND, method: MercuryMethod::SEND,
uri: self.spirc_internal.uri(), uri: self.spirc.uri(),
content_type: None, content_type: None,
payload: vec![pkt.write_to_bytes().unwrap()], payload: payload,
}) }).fire();
.fire();
} }
} }