1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-04 18:29:45 +02:00

Keep audio files cached in ram.

This commit is contained in:
Paul Lietar 2015-07-03 02:23:49 +02:00
parent 28a7db26be
commit 9ae452e22d
5 changed files with 77 additions and 37 deletions

View file

@ -1,6 +1,6 @@
use byteorder::{ByteOrder, BigEndian};
use std::cmp::min;
use std::collections::BitSet;
use std::collections::{BitSet, HashMap};
use std::io::{self, SeekFrom};
use std::slice::bytes::copy_memory;
use std::sync::{Arc, Condvar, Mutex};
@ -35,31 +35,7 @@ struct AudioFileData {
}
impl <'s> AudioFile <'s> {
pub fn new(session: &Session, file_id: FileId) -> AudioFile {
let mut it = session.stream(file_id, 0, 1).into_iter()
.filter_map(|event| {
match event {
StreamEvent::Header(id, ref data) if id == 0x3 => {
Some(BigEndian::read_u32(data) as usize * 4)
}
_ => None
}
});
let size = it.next().unwrap();
let bufsize = size + (CHUNK_SIZE - size % CHUNK_SIZE);
let shared = Arc::new(AudioFileShared {
file_id: file_id,
size: size,
data: Mutex::new(AudioFileData {
buffer: vec![0u8; bufsize],
bitmap: BitSet::with_capacity(bufsize / CHUNK_SIZE as usize)
}),
cond: Condvar::new(),
});
fn new(session: &Session, shared: Arc<AudioFileShared>) -> AudioFile {
let shared_ = shared.clone();
let (seek_tx, seek_rx) = mpsc::channel();
@ -164,4 +140,54 @@ impl <'s> io::Seek for AudioFile <'s> {
}
}
impl AudioFileShared {
fn new(session: &Session, file_id: FileId) -> Arc<AudioFileShared> {
let size = session.stream(file_id, 0, 1).into_iter()
.filter_map(|event| {
match event {
StreamEvent::Header(id, ref data) if id == 0x3 => {
Some(BigEndian::read_u32(data) as usize * 4)
}
_ => None
}
}).next().unwrap();
let bufsize = size + (CHUNK_SIZE - size % CHUNK_SIZE);
Arc::new(AudioFileShared {
file_id: file_id,
size: size,
data: Mutex::new(AudioFileData {
buffer: vec![0u8; bufsize],
bitmap: BitSet::with_capacity(bufsize / CHUNK_SIZE as usize)
}),
cond: Condvar::new(),
})
}
}
pub struct AudioFileManager {
cache: HashMap<FileId, Arc<AudioFileShared>>
}
impl AudioFileManager {
pub fn new() -> AudioFileManager {
AudioFileManager {
cache: HashMap::new()
}
}
pub fn request<'a> (&mut self, session: &'a Session, file_id: FileId) -> AudioFile<'a> {
let shared = self.cache
.get(&file_id)
.cloned()
.unwrap_or_else(|| {
println!("Cache miss");
let shared = AudioFileShared::new(session, file_id.clone());
self.cache.insert(file_id, shared.clone());
shared
});
AudioFile::new(session, shared)
}
}