فهرست منبع

Support using tremor instead of libvorbis for audio decoding.

Tremor is a fixed point / integer only Vorbis decoder.
This should improve playback performances on embedded platforms lacking
hardware floating point support.
Paul Lietar 10 سال پیش
والد
کامیت
ac5b34927f
5فایلهای تغییر یافته به همراه55 افزوده شده و 9 حذف شده
  1. 1 0
      .travis.yml
  2. 20 0
      Cargo.lock
  3. 2 0
      Cargo.toml
  4. 4 0
      src/lib.rs
  5. 28 9
      src/player.rs

+ 1 - 0
.travis.yml

@@ -12,6 +12,7 @@ addons:
 
 script:
     - cargo build
+    - cargo build --features with-tremor
     # Building without syntex only works on nightly
     - if [[ $(rustc --version) == *"nightly"* ]]; then
         cargo build --no-default-features;

+ 20 - 0
Cargo.lock

@@ -23,6 +23,7 @@ dependencies = [
  "tempfile 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
  "tiny_http 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)",
  "url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "vorbis 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -449,6 +450,25 @@ dependencies = [
  "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "tremor"
+version = "0.1.0"
+source = "git+https://github.com/plietar/rust-tremor#5ced876f3cffb041fcf31238da7f3273178029fe"
+dependencies = [
+ "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tremor-sys 0.1.0 (git+https://github.com/plietar/rust-tremor)",
+]
+
+[[package]]
+name = "tremor-sys"
+version = "0.1.0"
+source = "git+https://github.com/plietar/rust-tremor#5ced876f3cffb041fcf31238da7f3273178029fe"
+dependencies = [
+ "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "unicode-bidi"
 version = "0.2.3"

+ 2 - 0
Cargo.toml

@@ -41,6 +41,7 @@ portaudio       = { git = "https://github.com/mvdnes/portaudio-rs" }
 json_macros     = { git = "https://github.com/plietar/json_macros" }
 protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros" }
 shannon         = { git = "https://github.com/plietar/rust-shannon" }
+tremor          = { git = "https://github.com/plietar/rust-tremor", optional = true }
 
 [build-dependencies]
 vergen          = "~0.1.0"
@@ -51,4 +52,5 @@ json_macros     = { git = "https://github.com/plietar/json_macros" }
 [features]
 discovery = ["dns-sd"]
 with-syntex = ["syntex", "protobuf_macros/with-syntex", "json_macros/with-syntex"]
+with-tremor = ["tremor"]
 default = ["with-syntex"]

+ 4 - 0
src/lib.rs

@@ -21,7 +21,11 @@ extern crate time;
 extern crate tiny_http;
 extern crate tempfile;
 extern crate url;
+
+#[cfg(not(feature = "with-tremor"))]
 extern crate vorbis;
+#[cfg(feature = "with-tremor")]
+extern crate tremor as vorbis;
 
 #[cfg(feature = "dns-sd")]
 extern crate dns_sd;

+ 28 - 9
src/player.rs

@@ -3,6 +3,7 @@ use portaudio;
 use std::borrow::Cow;
 use std::sync::{mpsc, Mutex, Arc, MutexGuard};
 use std::thread;
+use std::io::{Read, Seek};
 use vorbis;
 
 use metadata::{FileFormat, Track, TrackRef};
@@ -11,6 +12,26 @@ use audio_decrypt::AudioDecrypt;
 use util::{self, SpotifyId, Subfile};
 use spirc::PlayStatus;
 
+#[cfg(not(feature = "with-tremor"))]
+fn vorbis_time_seek_ms<R>(decoder: &mut vorbis::Decoder<R>, ms: i64) -> Result<(), vorbis::VorbisError> where R: Read + Seek {
+    decoder.time_seek(ms as f64 / 1000f64)
+}
+
+#[cfg(not(feature = "with-tremor"))]
+fn vorbis_time_tell_ms<R>(decoder: &mut vorbis::Decoder<R>) -> Result<i64, vorbis::VorbisError> where R: Read + Seek {
+    decoder.time_tell().map(|t| (t / 1000f64) as i64)
+}
+
+#[cfg(feature = "with-tremor")]
+fn vorbis_time_seek_ms<R>(decoder: &mut vorbis::Decoder<R>, ms: i64) -> Result<(), vorbis::VorbisError> where R: Read + Seek {
+    decoder.time_seek(ms)
+}
+
+#[cfg(feature = "with-tremor")]
+fn vorbis_time_tell_ms<R>(decoder: &mut vorbis::Decoder<R>) -> Result<i64, vorbis::VorbisError> where R: Read + Seek {
+    decoder.time_tell()
+}
+
 pub type PlayerObserver = Box<Fn(&PlayerState) + Send>;
 
 pub struct Player {
@@ -195,7 +216,8 @@ impl PlayerInternal {
                         Subfile::new(
                         AudioDecrypt::new(key,
                         self.session.audio_file(file_id)), 0xa7)).unwrap());
-                    decoder.as_mut().unwrap().time_seek(position as f64 / 1000f64).unwrap();
+
+                    vorbis_time_seek_ms(decoder.as_mut().unwrap(), position as i64).unwrap()
 
                     self.update(|state| {
                         state.status = if play {
@@ -211,11 +233,10 @@ impl PlayerInternal {
                     });
                     println!("Load Done");
                 }
-                Some(PlayerCommand::Seek(ms)) => {
-                    decoder.as_mut().unwrap().time_seek(ms as f64 / 1000f64).unwrap();
+                Some(PlayerCommand::Seek(position)) => {
+                    vorbis_time_seek_ms(decoder.as_mut().unwrap(), position as i64).unwrap()
                     self.update(|state| {
-                        state.position_ms =
-                            (decoder.as_mut().unwrap().time_tell().unwrap() * 1000f64) as u32;
+                        state.position_ms = vorbis_time_tell_ms(decoder.as_mut().unwrap()).unwrap() as u32;
                         state.position_measured_at = util::now_ms();
 
                         true
@@ -224,8 +245,7 @@ impl PlayerInternal {
                 Some(PlayerCommand::Play) => {
                     self.update(|state| {
                         state.status = PlayStatus::kPlayStatusPlay;
-                        state.position_ms =
-                            (decoder.as_mut().unwrap().time_tell().unwrap() * 1000f64) as u32;
+                        state.position_ms = vorbis_time_tell_ms(decoder.as_mut().unwrap()).unwrap() as u32;
                         state.position_measured_at = util::now_ms();
                         true
                     });
@@ -236,8 +256,7 @@ impl PlayerInternal {
                     self.update(|state| {
                         state.status = PlayStatus::kPlayStatusPause;
                         state.update_time = util::now_ms();
-                        state.position_ms =
-                            (decoder.as_mut().unwrap().time_tell().unwrap() * 1000f64) as u32;
+                        state.position_ms = vorbis_time_tell_ms(decoder.as_mut().unwrap()).unwrap() as u32;
                         state.position_measured_at = util::now_ms();
                         true
                     });