mirror of
https://github.com/RustAudio/rodio
synced 2024-12-13 13:42:34 +00:00
Handle the volume in the engine core instead of the decoders
This commit is contained in:
parent
92a4567f08
commit
bc6f78de4c
4 changed files with 13 additions and 31 deletions
|
@ -9,9 +9,6 @@ mod wav;
|
|||
|
||||
/// Trait for objects that produce an audio stream.
|
||||
pub trait Decoder: Iterator /*+ ExactSizeIterator*/ { // TODO: should be exact size, but not enforced yet
|
||||
/// Changes the volume of the sound.
|
||||
fn set_volume(&mut self, f32);
|
||||
|
||||
/// Returns the total duration of the second in milliseconds.
|
||||
fn get_total_duration_ms(&self) -> u32;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use cpal::{self, Endpoint, Voice};
|
|||
use vorbis;
|
||||
|
||||
pub struct VorbisDecoder {
|
||||
reader: conversions::AmplifierIterator<Box<Iterator<Item=f32> + Send>>,
|
||||
reader: Box<Iterator<Item=f32> + Send>,
|
||||
}
|
||||
|
||||
impl VorbisDecoder {
|
||||
|
@ -31,16 +31,12 @@ impl VorbisDecoder {
|
|||
});
|
||||
|
||||
Ok(VorbisDecoder {
|
||||
reader: conversions::AmplifierIterator::new(Box::new(reader), 1.0),
|
||||
reader: Box::new(reader),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for VorbisDecoder {
|
||||
fn set_volume(&mut self, value: f32) {
|
||||
self.reader.set_amplification(value);
|
||||
}
|
||||
|
||||
fn get_total_duration_ms(&self) -> u32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use cpal::{self, Endpoint, Voice};
|
|||
use hound::WavReader;
|
||||
|
||||
pub struct WavDecoder {
|
||||
reader: conversions::AmplifierIterator<Box<Iterator<Item=f32> + Send>>,
|
||||
reader: Box<Iterator<Item=f32> + Send>,
|
||||
total_duration_ms: u32,
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ impl WavDecoder {
|
|||
let reader = conversions::DataConverter::new(reader);
|
||||
|
||||
Ok(WavDecoder {
|
||||
reader: conversions::AmplifierIterator::new(Box::new(reader), 1.0),
|
||||
reader: Box::new(reader),
|
||||
total_duration_ms: total_duration_ms,
|
||||
})
|
||||
}
|
||||
|
@ -78,10 +78,6 @@ fn is_wave<R>(mut data: R) -> bool where R: Read + Seek {
|
|||
}
|
||||
|
||||
impl Decoder for WavDecoder {
|
||||
fn set_volume(&mut self, value: f32) {
|
||||
self.reader.set_amplification(value);
|
||||
}
|
||||
|
||||
fn get_total_duration_ms(&self) -> u32 {
|
||||
self.total_duration_ms
|
||||
}
|
||||
|
|
|
@ -75,13 +75,6 @@ pub struct Handle<'a> {
|
|||
impl<'a> Handle<'a> {
|
||||
#[inline]
|
||||
pub fn set_volume(&self, value: f32) {
|
||||
// we try to touch the decoder directly from this thread
|
||||
if let Ok(mut decoder) = self.decoder.try_lock() {
|
||||
decoder.set_volume(value);
|
||||
}
|
||||
|
||||
// if `try_lock` failed, that means that the decoder is in use
|
||||
// therefore we use the backup plan of sending a message
|
||||
let commands = self.engine.commands.lock().unwrap();
|
||||
commands.send(Command::SetVolume(self.decoder.clone(), value)).unwrap();
|
||||
}
|
||||
|
@ -120,8 +113,8 @@ pub enum Command {
|
|||
}
|
||||
|
||||
fn background(rx: Receiver<Command>) {
|
||||
// for each endpoint name, stores the voice and the list of sounds
|
||||
let mut voices: HashMap<String, (Voice, Vec<Arc<Mutex<Decoder<Item=f32> + Send>>>)> = HashMap::new();
|
||||
// for each endpoint name, stores the voice and the list of sounds with their volume
|
||||
let mut voices: HashMap<String, (Voice, Vec<(Arc<Mutex<Decoder<Item=f32> + Send>>, f32)>)> = HashMap::new();
|
||||
|
||||
// list of sounds to stop playing
|
||||
let mut sounds_to_remove: Vec<Arc<Mutex<Decoder<Item=f32> + Send>>> = Vec::new();
|
||||
|
@ -140,14 +133,14 @@ fn background(rx: Receiver<Command>) {
|
|||
(voice, Vec::new())
|
||||
});
|
||||
|
||||
entry.1.push(decoder);
|
||||
entry.1.push((decoder, 1.0));
|
||||
},
|
||||
|
||||
Command::Stop(decoder) => {
|
||||
let decoder = &*decoder as *const _;
|
||||
for (_, &mut (_, ref mut sounds)) in voices.iter_mut() {
|
||||
sounds.retain(|dec| {
|
||||
&**dec as *const _ != decoder
|
||||
&*dec.0 as *const _ != decoder
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -156,9 +149,9 @@ fn background(rx: Receiver<Command>) {
|
|||
let decoder = &*decoder as *const _;
|
||||
for (_, &mut (_, ref mut sounds)) in voices.iter_mut() {
|
||||
if let Some(d) = sounds.iter_mut()
|
||||
.find(|dec| &***dec as *const _ != decoder)
|
||||
.find(|dec| &*dec.0 as *const _ == decoder)
|
||||
{
|
||||
d.lock().unwrap().set_volume(volume);
|
||||
d.1 = volume;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -169,7 +162,7 @@ fn background(rx: Receiver<Command>) {
|
|||
for decoder in mem::replace(&mut sounds_to_remove, Vec::new()) {
|
||||
let decoder = &*decoder as *const _;
|
||||
for (_, &mut (_, ref mut sounds)) in voices.iter_mut() {
|
||||
sounds.retain(|dec| &**dec as *const _ != decoder);
|
||||
sounds.retain(|dec| &*dec.0 as *const _ != decoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,14 +173,14 @@ fn background(rx: Receiver<Command>) {
|
|||
let num_sounds = sounds.len() as f32;
|
||||
let samples_iter = (0..).map(|_| {
|
||||
// FIXME: locking is slow
|
||||
sounds.iter().map(|s| s.lock().unwrap().next().unwrap_or(0.0) / num_sounds)
|
||||
sounds.iter().map(|s| s.0.lock().unwrap().next().unwrap_or(0.0) * s.1 / num_sounds)
|
||||
.fold(0.0, |a, b| a + b)
|
||||
});
|
||||
|
||||
// starting the output
|
||||
{
|
||||
let mut buffer = {
|
||||
let samples_to_write = voice.get_samples_rate().0 * voice.get_channels() as u32;
|
||||
let samples_to_write = voice.get_samples_rate().0 * voice.get_channels() as u32 * 17 / 1000;
|
||||
voice.append_data(samples_to_write as usize)
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue