Add support for lewton as an Vorbis decoder.

This commit is contained in:
Paul Lietar 2017-08-03 21:22:08 +01:00
parent ec8f80df75
commit d1447d2bfb
10 changed files with 250 additions and 151 deletions

49
Cargo.lock generated
View file

@ -225,6 +225,15 @@ name = "lazycell"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lewton"
version = "0.6.2"
source = "git+https://github.com/RustAudio/lewton#64a1f3fca7e1dfbfcc18ddcac07e845396c9b7bd"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ogg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.22" version = "0.2.22"
@ -244,25 +253,18 @@ version = "0.1.0"
dependencies = [ dependencies = [
"alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)", "alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)",
"base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.0-a.0 (git+https://github.com/hyperium/hyper)", "hyper 0.11.0-a.0 (git+https://github.com/hyperium/hyper)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libpulse-sys 0.0.0 (git+https://github.com/astro/libpulse-sys)", "libpulse-sys 0.0.0 (git+https://github.com/astro/libpulse-sys)",
"librespot-audio 0.1.0", "librespot-audio 0.1.0",
"librespot-core 0.1.0", "librespot-core 0.1.0",
"librespot-metadata 0.1.0", "librespot-metadata 0.1.0",
"librespot-protocol 0.1.0", "librespot-protocol 0.1.0",
"linear-map 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mdns 0.2.0 (git+https://github.com/plietar/rust-mdns)", "mdns 0.2.0 (git+https://github.com/plietar/rust-mdns)",
"num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"portaudio-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "portaudio-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)", "protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)",
@ -272,16 +274,10 @@ dependencies = [
"serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"shannon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-signal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-signal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)",
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vorbis 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -291,37 +287,32 @@ dependencies = [
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"lewton 0.6.2 (git+https://github.com/RustAudio/lewton)",
"librespot-core 0.1.0", "librespot-core 0.1.0",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (git+https://github.com/awmath/rust-crypto.git?branch=avx2)", "rust-crypto 0.2.36 (git+https://github.com/awmath/rust-crypto.git?branch=avx2)",
"tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)",
"vorbis 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "librespot-core" name = "librespot-core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)",
"base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.0-a.0 (git+https://github.com/hyperium/hyper)", "hyper 0.11.0-a.0 (git+https://github.com/hyperium/hyper)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libpulse-sys 0.0.0 (git+https://github.com/astro/libpulse-sys)",
"librespot-protocol 0.1.0", "librespot-protocol 0.1.0",
"linear-map 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mdns 0.2.0 (git+https://github.com/plietar/rust-mdns)",
"num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"portaudio-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)", "protobuf_macros 0.6.0 (git+https://github.com/plietar/rust-protobuf-macros)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
@ -331,15 +322,9 @@ dependencies = [
"serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
"shannon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "shannon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-signal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)",
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vorbis 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -498,6 +483,14 @@ dependencies = [
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ogg"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "ogg-sys" name = "ogg-sys"
version = "0.0.9" version = "0.0.9"
@ -1061,6 +1054,7 @@ dependencies = [
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
"checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b" "checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"
"checksum lewton 0.6.2 (git+https://github.com/RustAudio/lewton)" = "<none>"
"checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502" "checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502"
"checksum libpulse-sys 0.0.0 (git+https://github.com/astro/libpulse-sys)" = "<none>" "checksum libpulse-sys 0.0.0 (git+https://github.com/astro/libpulse-sys)" = "<none>"
"checksum linear-map 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f947d2a0ca958037e42a430bc7ea4369f97b60a2002bd927b84404509cc64cf" "checksum linear-map 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f947d2a0ca958037e42a430bc7ea4369f97b60a2002bd927b84404509cc64cf"
@ -1079,6 +1073,7 @@ dependencies = [
"checksum num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1a4bf6f9174aa5783a9b4cc892cacd11aebad6c69ad027a0b65c6ca5f8aa37" "checksum num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1a4bf6f9174aa5783a9b4cc892cacd11aebad6c69ad027a0b65c6ca5f8aa37"
"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
"checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" "checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167"
"checksum ogg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7137bf02687385302f4c0aecd77cfce052b69f5b4ee937be778e125c62f67e30"
"checksum ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a95b8c172e17df1a41bf8d666301d3b2c4efeb90d9d0415e2a4dc0668b35fdb2" "checksum ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a95b8c172e17df1a41bf8d666301d3b2c4efeb90d9d0415e2a4dc0668b35fdb2"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum portaudio-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "029e0ab393b44b2d825efbc755cae51c36be7a99d91356b2052be0ed05836636" "checksum portaudio-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "029e0ab393b44b2d825efbc755cae51c36be7a99d91356b2052be0ed05836636"

View file

@ -30,45 +30,29 @@ path = "metadata"
path = "protocol" path = "protocol"
[dependencies] [dependencies]
base64 = "0.5.0" base64 = "0.5.0"
bit-set = "0.4.0" env_logger = "0.4.0"
byteorder = "1.0" futures = "0.1.8"
env_logger = "0.4.0" getopts = "0.2.14"
getopts = "0.2.14" hyper = { git = "https://github.com/hyperium/hyper" }
hyper = { git = "https://github.com/hyperium/hyper" } log = "0.3.5"
lazy_static = "0.2.0" mdns = { git = "https://github.com/plietar/rust-mdns" }
linear-map = "1.0" num-bigint = "0.1.35"
log = "0.3.5" protobuf = "1.1"
num-bigint = "0.1.35" rand = "0.3.13"
num-integer = "0.1.32" rpassword = "0.3.0"
num-traits = "0.1.36" rust-crypto = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" }
protobuf = "1.1" serde = "0.9.6"
rand = "0.3.13" serde_derive = "0.9.6"
rpassword = "0.3.0" serde_json = "0.9.5"
rust-crypto = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" } tokio-core = "0.1.2"
serde = "0.9.6" tokio-signal = "0.1.2"
serde_json = "0.9.5" url = "1.3"
serde_derive = "0.9.6"
shannon = "0.2.0"
tempfile = "2.1"
url = "1.3"
vorbis = "0.1.0"
tremor = { git = "https://github.com/plietar/rust-tremor", optional = true }
alsa = { git = "https://github.com/plietar/rust-alsa", optional = true } alsa = { git = "https://github.com/plietar/rust-alsa", optional = true }
portaudio-rs = { version = "0.3.0", optional = true } portaudio-rs = { version = "0.3.0", optional = true }
libpulse-sys = { git = "https://github.com/astro/libpulse-sys", optional = true } libpulse-sys = { git = "https://github.com/astro/libpulse-sys", optional = true }
mdns = { git = "https://github.com/plietar/rust-mdns" }
error-chain = { version = "0.9.0", default_features = false }
futures = "0.1.8"
tokio-core = "0.1.2"
tokio-proto = "0.1.0"
tokio-signal = "0.1"
uuid = { version = "0.4", features = ["v4"] }
[build-dependencies] [build-dependencies]
rand = "0.3.13" rand = "0.3.13"
vergen = "0.1.0" vergen = "0.1.0"
@ -79,7 +63,8 @@ alsa-backend = ["alsa"]
portaudio-backend = ["portaudio-rs"] portaudio-backend = ["portaudio-rs"]
pulseaudio-backend = ["libpulse-sys"] pulseaudio-backend = ["libpulse-sys"]
with-tremor = ["tremor"] with-tremor = ["librespot-audio/with-tremor"]
with-lewton = ["librespot-audio/with-lewton"]
default = ["portaudio-backend"] default = ["portaudio-backend"]

View file

@ -3,15 +3,23 @@ name = "librespot-audio"
version = "0.1.0" version = "0.1.0"
authors = ["Paul Lietar <paul@lietar.net>"] authors = ["Paul Lietar <paul@lietar.net>"]
[dependencies.librespot-core]
path = "../core"
[dependencies] [dependencies]
bit-set = "0.4.0" bit-set = "0.4.0"
byteorder = "1.0" byteorder = "1.0"
rust-crypto = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" }
futures = "0.1.8" futures = "0.1.8"
log = "0.3.5" log = "0.3.5"
num-bigint = "0.1.35" num-bigint = "0.1.35"
num-traits = "0.1.36" num-traits = "0.1.36"
rust-crypto = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" }
tempfile = "2.1" tempfile = "2.1"
vorbis = "0.1.0"
[dependencies.librespot-core] tremor = { git = "https://github.com/plietar/rust-tremor", optional = true }
path = "../core" lewton = { git = "https://github.com/RustAudio/lewton", optional = true }
[features]
with-tremor = ["tremor"]
with-lewton = ["lewton"]

View file

@ -0,0 +1,77 @@
extern crate lewton;
use self::lewton::inside_ogg::OggStreamReader;
use std::io::{Read, Seek};
use std::fmt;
use std::error;
pub struct VorbisDecoder<R: Read + Seek>(OggStreamReader<R>);
pub struct VorbisPacket(Vec<i16>);
pub struct VorbisError(lewton::VorbisError);
impl <R> VorbisDecoder<R>
where R: Read + Seek
{
pub fn new(input: R) -> Result<VorbisDecoder<R>, VorbisError> {
Ok(VorbisDecoder(OggStreamReader::new(input)?))
}
pub fn seek(&mut self, ms: i64) -> Result<(), VorbisError> {
let absgp = ms * 44100 / 1000;
self.0.seek_absgp_pg(absgp as u64)?;
Ok(())
}
pub fn next_packet(&mut self) -> Result<Option<VorbisPacket>, VorbisError> {
use self::lewton::VorbisError::BadAudio;
use self::lewton::audio::AudioReadError::AudioIsHeader;
loop {
match self.0.read_dec_packet_itl() {
Ok(Some(packet)) => return Ok(Some(VorbisPacket(packet))),
Ok(None) => return Ok(None),
Err(BadAudio(AudioIsHeader)) => (),
Err(err) => return Err(err.into()),
}
}
}
}
impl VorbisPacket {
pub fn data(&self) -> &[i16] {
&self.0
}
pub fn data_mut(&mut self) -> &mut [i16] {
&mut self.0
}
}
impl From<lewton::VorbisError> for VorbisError {
fn from(err: lewton::VorbisError) -> VorbisError {
VorbisError(err)
}
}
impl fmt::Debug for VorbisError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl fmt::Display for VorbisError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl error::Error for VorbisError {
fn description(&self) -> &str {
error::Error::description(&self.0)
}
fn cause(&self) -> Option<&error::Error> {
error::Error::cause(&self.0)
}
}

View file

@ -13,5 +13,15 @@ extern crate librespot_core as core;
mod fetch; mod fetch;
mod decrypt; mod decrypt;
#[cfg(not(feature = "with-lewton"))]
mod libvorbis_decoder;
#[cfg(feature = "with-lewton")]
mod lewton_decoder;
pub use fetch::{AudioFile, AudioFileOpen}; pub use fetch::{AudioFile, AudioFileOpen};
pub use decrypt::AudioDecrypt; pub use decrypt::AudioDecrypt;
#[cfg(not(feature = "with-lewton"))]
pub use libvorbis_decoder::{VorbisDecoder, VorbisPacket, VorbisError};
#[cfg(feature = "with-lewton")]
pub use lewton_decoder::{VorbisDecoder, VorbisPacket, VorbisError};

View file

@ -0,0 +1,80 @@
#[cfg(not(feature = "with-tremor"))] extern crate vorbis;
#[cfg(feature = "with-tremor")] extern crate tremor as vorbis;
use std::io::{Read, Seek};
use std::fmt;
use std::error;
pub struct VorbisDecoder<R: Read + Seek>(vorbis::Decoder<R>);
pub struct VorbisPacket(vorbis::Packet);
pub struct VorbisError(vorbis::VorbisError);
impl <R> VorbisDecoder<R>
where R: Read + Seek
{
pub fn new(input: R) -> Result<VorbisDecoder<R>, VorbisError> {
Ok(VorbisDecoder(vorbis::Decoder::new(input)?))
}
#[cfg(not(feature = "with-tremor"))]
pub fn seek(&mut self, ms: i64) -> Result<(), VorbisError> {
self.0.time_seek(ms as f64 / 1000f64)?;
Ok(())
}
#[cfg(feature = "with-tremor")]
pub fn seek(&mut self, ms: i64) -> Result<(), VorbisError> {
self.0.time_seek(ms)?;
Ok(())
}
pub fn next_packet(&mut self) -> Result<Option<VorbisPacket>, VorbisError> {
loop {
match self.0.packets().next() {
Some(Ok(packet)) => return Ok(Some(VorbisPacket(packet))),
None => return Ok(None),
Some(Err(vorbis::VorbisError::Hole)) => (),
Some(Err(err)) => return Err(err.into()),
}
}
}
}
impl VorbisPacket {
pub fn data(&self) -> &[i16] {
&self.0.data
}
pub fn data_mut(&mut self) -> &mut [i16] {
&mut self.0.data
}
}
impl From<vorbis::VorbisError> for VorbisError {
fn from(err: vorbis::VorbisError) -> VorbisError {
VorbisError(err)
}
}
impl fmt::Debug for VorbisError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl fmt::Display for VorbisError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl error::Error for VorbisError {
fn description(&self) -> &str {
error::Error::description(&self.0)
}
fn cause(&self) -> Option<&error::Error> {
error::Error::cause(&self.0)
}
}

View file

@ -8,46 +8,28 @@ build = "build.rs"
path = "../protocol" path = "../protocol"
[dependencies] [dependencies]
base64 = "0.5.0" base64 = "0.5.0"
bit-set = "0.4.0" byteorder = "1.0"
byteorder = "1.0"
env_logger = "0.4.0"
getopts = "0.2.14"
hyper = { git = "https://github.com/hyperium/hyper" }
lazy_static = "0.2.0"
linear-map = "1.0"
log = "0.3.5"
num-bigint = "0.1.35"
num-integer = "0.1.32"
num-traits = "0.1.36"
protobuf = "1.1"
rand = "0.3.13"
rpassword = "0.3.0"
rust-crypto = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" }
serde = "0.9.6"
serde_json = "0.9.5"
serde_derive = "0.9.6"
shannon = "0.2.0"
tempfile = "2.1"
url = "1.3"
vorbis = "0.1.0"
tremor = { git = "https://github.com/plietar/rust-tremor", optional = true }
alsa = { git = "https://github.com/plietar/rust-alsa", optional = true }
portaudio-rs = { version = "0.3.0", optional = true }
libpulse-sys = { git = "https://github.com/astro/libpulse-sys", optional = true }
mdns = { git = "https://github.com/plietar/rust-mdns" }
error-chain = { version = "0.9.0", default_features = false } error-chain = { version = "0.9.0", default_features = false }
futures = "0.1.8" futures = "0.1.8"
hyper = { git = "https://github.com/hyperium/hyper" }
lazy_static = "0.2.0"
log = "0.3.5"
num-bigint = "0.1.35"
num-integer = "0.1.32"
num-traits = "0.1.36"
protobuf = "1.1"
rand = "0.3.13"
rpassword = "0.3.0"
rust-crypto = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" }
serde = "0.9.6"
serde_derive = "0.9.6"
serde_json = "0.9.5"
shannon = "0.2.0"
tokio-core = "0.1.2" tokio-core = "0.1.2"
tokio-proto = "0.1.0"
tokio-signal = "0.1"
uuid = { version = "0.4", features = ["v4"] } uuid = { version = "0.4", features = ["v4"] }
[build-dependencies] [build-dependencies]
rand = "0.3.13"
vergen = "0.1.0"
protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros", features = ["with-syntex"] } protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros", features = ["with-syntex"] }
rand = "0.3.13"
vergen = "0.1.0"

View file

@ -10,13 +10,9 @@
#[macro_use] extern crate serde_derive; #[macro_use] extern crate serde_derive;
extern crate base64; extern crate base64;
extern crate bit_set;
extern crate byteorder; extern crate byteorder;
extern crate crypto; extern crate crypto;
extern crate getopts;
extern crate hyper; extern crate hyper;
extern crate linear_map;
extern crate mdns;
extern crate num_bigint; extern crate num_bigint;
extern crate num_integer; extern crate num_integer;
extern crate num_traits; extern crate num_traits;
@ -26,13 +22,10 @@ extern crate rpassword;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate shannon; extern crate shannon;
extern crate tempfile;
extern crate tokio_core; extern crate tokio_core;
extern crate tokio_proto;
extern crate url;
extern crate uuid; extern crate uuid;
pub extern crate librespot_protocol as protocol; extern crate librespot_protocol as protocol;
#[macro_use] mod component; #[macro_use] mod component;
pub mod apresolve; pub mod apresolve;

View file

@ -10,38 +10,21 @@
#[macro_use] extern crate serde_derive; #[macro_use] extern crate serde_derive;
extern crate base64; extern crate base64;
extern crate bit_set;
extern crate byteorder;
extern crate crypto; extern crate crypto;
extern crate futures; extern crate futures;
extern crate getopts;
extern crate hyper; extern crate hyper;
extern crate linear_map;
extern crate mdns; extern crate mdns;
extern crate num_bigint; extern crate num_bigint;
extern crate num_integer;
extern crate num_traits;
extern crate protobuf; extern crate protobuf;
extern crate rand; extern crate rand;
extern crate rpassword;
extern crate serde;
extern crate shannon;
extern crate tempfile;
extern crate tokio_core; extern crate tokio_core;
extern crate tokio_proto;
extern crate url; extern crate url;
extern crate uuid;
pub extern crate librespot_audio as audio; pub extern crate librespot_audio as audio;
pub extern crate librespot_core as core; pub extern crate librespot_core as core;
pub extern crate librespot_protocol as protocol; pub extern crate librespot_protocol as protocol;
pub extern crate librespot_metadata as metadata; pub extern crate librespot_metadata as metadata;
#[cfg(not(feature = "with-tremor"))]
extern crate vorbis;
#[cfg(feature = "with-tremor")]
extern crate tremor as vorbis;
#[cfg(feature = "alsa-backend")] #[cfg(feature = "alsa-backend")]
extern crate alsa; extern crate alsa;

View file

@ -1,20 +1,18 @@
use futures::sync::oneshot; use futures::sync::oneshot;
use futures::{future, Future}; use futures::{future, Future};
use std::borrow::Cow; use std::borrow::Cow;
use std::io::{Read, Seek};
use std::mem; use std::mem;
use std::sync::mpsc::{RecvError, TryRecvError}; use std::sync::mpsc::{RecvError, TryRecvError};
use std::thread; use std::thread;
use std; use std;
use vorbis::{self, VorbisError};
use core::config::{Bitrate, PlayerConfig}; use core::config::{Bitrate, PlayerConfig};
use core::session::Session; use core::session::Session;
use core::util::{self, SpotifyId, Subfile}; use core::util::{self, SpotifyId, Subfile};
use audio_backend::Sink; use audio_backend::Sink;
use audio::AudioDecrypt; use audio::{AudioFile, AudioDecrypt};
use audio::AudioFile; use audio::{VorbisDecoder, VorbisPacket};
use metadata::{FileFormat, Track, Metadata}; use metadata::{FileFormat, Track, Metadata};
use mixer::AudioFilter; use mixer::AudioFilter;
@ -100,7 +98,7 @@ impl Player {
} }
} }
type Decoder = vorbis::Decoder<Subfile<AudioDecrypt<AudioFile>>>; type Decoder = VorbisDecoder<Subfile<AudioDecrypt<AudioFile>>>;
enum PlayerState { enum PlayerState {
Stopped, Stopped,
Paused { Paused {
@ -196,7 +194,7 @@ impl PlayerInternal {
} }
let packet = if let PlayerState::Playing { ref mut decoder, .. } = self.state { let packet = if let PlayerState::Playing { ref mut decoder, .. } = self.state {
Some(decoder.packets().next()) Some(decoder.next_packet().expect("Vorbis error"))
} else { None }; } else { None };
if let Some(packet) = packet { if let Some(packet) = packet {
@ -205,18 +203,16 @@ impl PlayerInternal {
} }
} }
fn handle_packet(&mut self, packet: Option<Result<vorbis::Packet, VorbisError>>) { fn handle_packet(&mut self, packet: Option<VorbisPacket>) {
match packet { match packet {
Some(Ok(mut packet)) => { Some(mut packet) => {
if let Some(ref editor) = self.audio_filter { if let Some(ref editor) = self.audio_filter {
editor.modify_stream(&mut packet.data) editor.modify_stream(&mut packet.data_mut())
}; };
self.sink.write(&packet.data).unwrap(); self.sink.write(&packet.data()).unwrap();
} }
Some(Err(vorbis::VorbisError::Hole)) => (),
Some(Err(e)) => panic!("Vorbis error {:?}", e),
None => { None => {
self.sink.stop().unwrap(); self.sink.stop().unwrap();
self.run_onstop(); self.run_onstop();
@ -270,7 +266,7 @@ impl PlayerInternal {
PlayerCommand::Seek(position) => { PlayerCommand::Seek(position) => {
if let Some(decoder) = self.state.decoder() { if let Some(decoder) = self.state.decoder() {
match vorbis_time_seek_ms(decoder, position as i64) { match decoder.seek(position as i64) {
Ok(_) => (), Ok(_) => (),
Err(err) => error!("Vorbis error: {:?}", err), Err(err) => error!("Vorbis error: {:?}", err),
} }
@ -379,9 +375,9 @@ impl PlayerInternal {
let encrypted_file = AudioFile::open(&self.session, file_id).wait().unwrap(); let encrypted_file = AudioFile::open(&self.session, file_id).wait().unwrap();
let audio_file = Subfile::new(AudioDecrypt::new(key, encrypted_file), 0xa7); let audio_file = Subfile::new(AudioDecrypt::new(key, encrypted_file), 0xa7);
let mut decoder = vorbis::Decoder::new(audio_file).unwrap(); let mut decoder = VorbisDecoder::new(audio_file).unwrap();
match vorbis_time_seek_ms(&mut decoder, position) { match decoder.seek(position) {
Ok(_) => (), Ok(_) => (),
Err(err) => error!("Vorbis error: {:?}", err), Err(err) => error!("Vorbis error: {:?}", err),
} }
@ -398,16 +394,6 @@ impl Drop for PlayerInternal {
} }
} }
#[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(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)
}
impl ::std::fmt::Debug for PlayerCommand { impl ::std::fmt::Debug for PlayerCommand {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match *self { match *self {