Skip to content

Commit

Permalink
Add play methods to audio Output
Browse files Browse the repository at this point in the history
  • Loading branch information
torkleyy committed Oct 17, 2017
1 parent 4c534ab commit b267826
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 84 deletions.
4 changes: 1 addition & 3 deletions examples/04_pong/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@ pub fn initialise_audio(world: &mut World) {

/// Plays the bounce sound when a ball hits a side or a paddle.
pub fn play_bounce(sounds: &Sounds, storage: &AssetStorage<Source>, output: &Option<Output>) {
use amethyst::audio::play::play_once;

if let Some(ref output) = output.as_ref() {
if let Some(sound) = storage.get(&sounds.bounce_sfx) {
play_once(sound, 1.0, &output);
output.play_once(sound, 1.0);
}
}
}
6 changes: 2 additions & 4 deletions examples/04_pong/systems/winner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ impl<'s> System<'s> for WinnerSystem {
};

if did_hit {
use amethyst::audio::play::play_once;

// Reset the ball.
ball.velocity[0] = -ball.velocity[0];
transform.translation[0] = ARENA_WIDTH / 2.0;
Expand All @@ -58,9 +56,9 @@ impl<'s> System<'s> for WinnerSystem {
);

// Play audio.
if let Some(ref audio_output) = *audio_output {
if let Some(ref output) = *audio_output {
if let Some(sound) = storage.get(&sounds.score_sfx) {
play_once(sound, 1.0, &audio_output);
output.play_once(sound, 1.0);
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/audio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pub use self::formats::{FlacFormat, OggFormat, WavFormat};
pub use self::sink::AudioSink;
pub use self::source::{Source, SourceHandle};

pub mod play;
pub mod output;

use std::error::Error;
Expand Down
78 changes: 72 additions & 6 deletions src/audio/output.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
//! Provides structures and functions used to get audio outputs.
// We have to use types from this to provide an output iterator type.
extern crate cpal;

use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::io::Cursor;

use cpal::{default_endpoint, endpoints};
use cpal::EndpointsIterator;
use rodio::{Decoder, Endpoint, Sink, Source as RSource};

use self::cpal::{default_endpoint, endpoints};
use self::cpal::EndpointsIterator;
use rodio::Endpoint;
use super::DecoderError;
use super::source::Source;

/// A speaker(s) through which audio can be played.
///
/// By convention, the default output is stored as a resouce in the `World`.
pub struct Output {
pub(crate) endpoint: Endpoint,
}
Expand All @@ -19,6 +22,69 @@ impl Output {
pub fn name(&self) -> String {
self.endpoint.name()
}

/// Play a sound once. A volume of 1.0 is unchanged, while 0.0 is silent.
///
/// This will return an Error if the loaded audio file in source could not be decoded.
pub fn try_play_once(&self, source: &Source, volume: f32)
-> Result<(), DecoderError> {
let sink = Sink::new(&self.endpoint);
match Decoder::new(Cursor::new(source.clone())) {
Ok(source) => {
sink.append(source.amplify(volume));
sink.detach();
Ok(())
}

// There is one and only one error that can be returned, which is unrecognized format
// See documentation for DecoderError here:
// https://docs.rs/rodio/0.5.1/rodio/decoder/enum.DecoderError.html
Err(err) => {
eprintln!("Error while playing sound: {:?}", err);
Err(DecoderError)
}
}
}

/// Play a sound once. A volume of 1.0 is unchanged, while 0.0 is silent.
///
/// This may silently fail, in order to get error information use `try_play_once`.
pub fn play_once(&self, source: &Source, volume: f32) {
if let Err(err) = self.try_play_once(source, volume) {
eprintln!("An error occurred while trying to play a sound: {:?}", err);
}
}

/// Play a sound n times. A volume of 1.0 is unchanged, while 0.0 is silent.
///
/// This may silently fail, in order to get error information use `try_play_n_times`.
pub fn play_n_times(&self, source: &Source, volume: f32, n: u16) {
if let Err(err) = self.try_play_n_times(source, volume, n) {
eprintln!("An error occurred while trying to play a sound: {:?}", err);
}
}

/// Play a sound n times. A volume of 1.0 is unchanged, while 0.0 is silent.
///
/// This will return an Error if the loaded audio file in source could not be decoded.
pub fn try_play_n_times(
&self,
source: &Source,
volume: f32,
n: u16,
) -> Result<(), DecoderError> {
let sink = Sink::new(&self.endpoint);
for _ in 0..n {
sink.append(
Decoder::new(Cursor::new(source.clone()))
.map_err(|_| DecoderError)?
.amplify(volume),
);
}
sink.detach();
Ok(())
}

}

impl Debug for Output {
Expand Down
70 changes: 0 additions & 70 deletions src/audio/play.rs

This file was deleted.

1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub extern crate shrev;
pub extern crate winit;

extern crate cgmath;
extern crate cpal;
extern crate crossbeam;
#[macro_use]
extern crate derivative;
Expand Down

0 comments on commit b267826

Please sign in to comment.