mirror of
https://github.com/RustAudio/rodio
synced 2024-12-12 21:22:36 +00:00
Add set_volume to Handle
This commit is contained in:
parent
b088c15740
commit
338114d93e
7 changed files with 95 additions and 3 deletions
|
@ -6,7 +6,8 @@ fn main() {
|
|||
let endpoint = rodio::get_default_endpoint().unwrap();
|
||||
|
||||
let file = std::fs::File::open("examples/beep.wav").unwrap();
|
||||
let beep1 = rodio::play_once(&endpoint, BufReader::new(file));
|
||||
let mut beep1 = rodio::play_once(&endpoint, BufReader::new(file));
|
||||
beep1.set_volume(0.2);
|
||||
|
||||
std::thread::sleep_ms(1000);
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ pub fn convert_and_write<I, S>(mut samples: I, output: &mut UnknownTypeBuffer)
|
|||
/// Trait for containers that contain PCM data.
|
||||
pub trait Sample: cpal::Sample {
|
||||
fn lerp(first: Self, second: Self, numerator: u32, denominator: u32) -> Self;
|
||||
fn amplify(self, value: f32) -> Self;
|
||||
|
||||
fn zero_value() -> Self;
|
||||
|
||||
|
@ -57,6 +58,11 @@ impl Sample for u16 {
|
|||
(first as u32 + (second as u32 - first as u32) * numerator / denominator) as u16
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn amplify(self, value: f32) -> u16 {
|
||||
((self as f32) * value) as u16
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn zero_value() -> u16 {
|
||||
32768
|
||||
|
@ -88,6 +94,11 @@ impl Sample for i16 {
|
|||
(first as i32 + (second as i32 - first as i32) * numerator as i32 / denominator as i32) as i16
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn amplify(self, value: f32) -> i16 {
|
||||
((self as f32) * value) as i16
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn zero_value() -> i16 {
|
||||
0
|
||||
|
@ -123,6 +134,11 @@ impl Sample for f32 {
|
|||
first + (second - first) * numerator as f32 / denominator as f32
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn amplify(self, value: f32) -> f32 {
|
||||
self * value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn zero_value() -> f32 {
|
||||
0.0
|
||||
|
@ -345,6 +361,43 @@ impl<I> Iterator for SamplesRateConverter<I> where I: Iterator, I::Item: Sample
|
|||
impl<I> ExactSizeIterator for SamplesRateConverter<I>
|
||||
where I: ExactSizeIterator, I::Item: Sample + Clone {}
|
||||
|
||||
pub struct AmplifierIterator<I> where I: Iterator {
|
||||
input: I,
|
||||
amplication: f32,
|
||||
}
|
||||
|
||||
impl<I> AmplifierIterator<I> where I: Iterator {
|
||||
#[inline]
|
||||
pub fn new(input: I, amplication: f32) -> AmplifierIterator<I> {
|
||||
AmplifierIterator {
|
||||
input: input,
|
||||
amplication: amplication,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_amplification(&mut self, new_value: f32) {
|
||||
self.amplication = new_value;
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> Iterator for AmplifierIterator<I> where I: Iterator, I::Item: Sample {
|
||||
type Item = I::Item;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<I::Item> {
|
||||
self.input.next().map(|value| value.amplify(self.amplication))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.input.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> ExactSizeIterator for AmplifierIterator<I>
|
||||
where I: ExactSizeIterator, I::Item: Sample {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::Sample;
|
||||
|
|
|
@ -12,6 +12,9 @@ pub trait Decoder {
|
|||
/// Appends data to the voice. Returns the number of nanoseconds after which new data will need
|
||||
/// to have been submitted.
|
||||
fn write(&mut self) -> u64;
|
||||
|
||||
/// Changes the volume of the sound.
|
||||
fn set_volume(&mut self, f32);
|
||||
}
|
||||
|
||||
/// Builds a new `Decoder` from a data stream by determining the correct format.
|
||||
|
|
|
@ -63,4 +63,8 @@ impl Decoder for VorbisDecoder {
|
|||
|
||||
len as u64 * 1000000000 / self.voice.get_samples_rate().0 as u64
|
||||
}
|
||||
|
||||
fn set_volume(&mut self, _: f32) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::io::{Read, Seek, SeekFrom};
|
||||
use std::cmp;
|
||||
use std::cmp::Ordering;
|
||||
use super::Decoder;
|
||||
use super::conversions;
|
||||
|
@ -8,7 +9,7 @@ use hound::WavReader;
|
|||
use hound::WavSpec;
|
||||
|
||||
pub struct WavDecoder {
|
||||
reader: Box<Iterator<Item=i16> + Send>,
|
||||
reader: conversions::AmplifierIterator<Box<Iterator<Item=i16> + Send>>,
|
||||
voice: Voice,
|
||||
}
|
||||
|
||||
|
@ -59,7 +60,7 @@ impl WavDecoder {
|
|||
voice.get_samples_rate());
|
||||
|
||||
Ok(WavDecoder {
|
||||
reader: Box::new(reader),
|
||||
reader: conversions::AmplifierIterator::new(Box::new(reader), 1.0),
|
||||
voice: voice,
|
||||
})
|
||||
}
|
||||
|
@ -108,6 +109,8 @@ fn is_wave<R>(mut data: R) -> bool where R: Read + Seek {
|
|||
impl Decoder for WavDecoder {
|
||||
fn write(&mut self) -> u64 {
|
||||
let (min, _) = self.reader.size_hint();
|
||||
let min = cmp::min(min, 10240); // using a minimal value so that filters get applied
|
||||
// quickly
|
||||
|
||||
if min == 0 {
|
||||
// finished
|
||||
|
@ -127,4 +130,8 @@ impl Decoder for WavDecoder {
|
|||
|
||||
duration
|
||||
}
|
||||
|
||||
fn set_volume(&mut self, value: f32) {
|
||||
self.reader.set_amplification(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,12 @@ pub struct Handle<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Handle<'a> {
|
||||
#[inline]
|
||||
pub fn set_volume(&mut self, value: f32) {
|
||||
let commands = self.engine.commands.lock().unwrap();
|
||||
commands.send(Command::SetVolume(self.id, value)).unwrap();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn stop(self) {
|
||||
let commands = self.engine.commands.lock().unwrap();
|
||||
|
@ -70,6 +76,7 @@ impl<'a> Handle<'a> {
|
|||
pub enum Command {
|
||||
Play(usize, Box<Decoder + Send>),
|
||||
Stop(usize),
|
||||
SetVolume(usize, f32),
|
||||
}
|
||||
|
||||
fn background(rx: Receiver<Command>) {
|
||||
|
@ -86,6 +93,14 @@ fn background(rx: Receiver<Command>) {
|
|||
Command::Stop(id) => {
|
||||
sounds.retain(|&(id2, _)| id2 != id)
|
||||
},
|
||||
|
||||
Command::SetVolume(id, volume) => {
|
||||
if let Some(&mut (_, ref mut d)) = sounds.iter_mut()
|
||||
.find(|&&mut (i, _)| i == id)
|
||||
{
|
||||
d.set_volume(volume);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,15 @@ lazy_static! {
|
|||
pub struct Handle(engine::Handle<'static>);
|
||||
|
||||
impl Handle {
|
||||
/// Changes the volume of the sound.
|
||||
///
|
||||
/// The value `1.0` is the "normal" volume (unfiltered input). Any value other than 1.0 will
|
||||
/// multiply each sample by this value.
|
||||
#[inline]
|
||||
pub fn set_volume(&mut self, value: f32) {
|
||||
self.0.set_volume(value);
|
||||
}
|
||||
|
||||
/// Stops the sound.
|
||||
#[inline]
|
||||
pub fn stop(self) {
|
||||
|
|
Loading…
Reference in a new issue