Set the default volume to 100%, and add a fast path to volume control.

This commit is contained in:
Paul Lietar 2016-02-05 20:54:47 +00:00
parent dfabbe5aa5
commit 526c54702b

View file

@ -1,5 +1,6 @@
use eventual::{self, Async}; use eventual::{self, Async};
use portaudio; use portaudio;
use std::borrow::Cow;
use std::sync::{mpsc, Mutex, Arc, MutexGuard}; use std::sync::{mpsc, Mutex, Arc, MutexGuard};
use std::thread; use std::thread;
use vorbis; use vorbis;
@ -55,7 +56,7 @@ impl Player {
position_ms: 0, position_ms: 0,
position_measured_at: 0, position_measured_at: 0,
update_time: util::now_ms(), update_time: util::now_ms(),
volume: 0x8000, volume: 0xFFFF,
end_of_track: false, end_of_track: false,
})); }));
@ -114,6 +115,21 @@ impl Player {
} }
} }
fn apply_volume(volume: u16, data: &[i16]) -> Cow<[i16]> {
// Fast path when volume is 100%
if volume == 0xFFFF {
Cow::Borrowed(data)
} else {
Cow::Owned(data.iter()
.map(|&x| {
(x as i32
* volume as i32
/ 0xFFFF) as i16
})
.collect())
}
}
impl PlayerInternal { impl PlayerInternal {
fn run(self) { fn run(self) {
portaudio::initialize().unwrap(); portaudio::initialize().unwrap();
@ -247,14 +263,8 @@ impl PlayerInternal {
if self.state.lock().unwrap().status == PlayStatus::kPlayStatusPlay { if self.state.lock().unwrap().status == PlayStatus::kPlayStatusPlay {
match decoder.as_mut().unwrap().packets().next() { match decoder.as_mut().unwrap().packets().next() {
Some(Ok(packet)) => { Some(Ok(packet)) => {
let buffer = packet.data let buffer = apply_volume(self.state.lock().unwrap().volume,
.iter() &packet.data);
.map(|&x| {
(x as i32
* self.state.lock().unwrap().volume as i32
/ 0xFFFF) as i16
})
.collect::<Vec<i16>>();
match stream.write(&buffer) { match stream.write(&buffer) {
Ok(_) => (), Ok(_) => (),
Err(portaudio::PaError::OutputUnderflowed) => eprintln!("Underflow"), Err(portaudio::PaError::OutputUnderflowed) => eprintln!("Underflow"),