From 76820904814ad8e662662fa930096973f9b04227 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Tue, 11 Aug 2020 14:42:39 -0700 Subject: [PATCH 1/2] init draft of custom rodio source for audio --- .gitignore | 3 +- crates/bevy_audio/src/audio_output.rs | 43 +++++++++++++++++---------- crates/bevy_audio/src/audio_source.rs | 16 +++++++++- crates/bevy_audio/src/lib.rs | 9 ++++-- examples/audio/audio.rs | 2 +- 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index b3c22eedfbd83..840c8c0bb1390 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ **/*.rs.bk Cargo.lock .cargo/config -/.idea \ No newline at end of file +/.idea +/.vscode diff --git a/crates/bevy_audio/src/audio_output.rs b/crates/bevy_audio/src/audio_output.rs index d81157070d9b8..42fdeabd1e234 100644 --- a/crates/bevy_audio/src/audio_output.rs +++ b/crates/bevy_audio/src/audio_output.rs @@ -1,17 +1,23 @@ -use crate::AudioSource; +use crate::Decodable; use bevy_asset::{Assets, Handle}; use bevy_ecs::Res; use parking_lot::RwLock; -use rodio::{Decoder, Device, Sink}; -use std::{collections::VecDeque, io::Cursor}; +use rodio::{Device, Sink}; +use std::collections::VecDeque; /// Used to play audio on the current "audio device" -pub struct AudioOutput { +pub struct AudioOutput

+where + P: Decodable, +{ device: Device, - queue: RwLock>>, + queue: RwLock>>, } -impl Default for AudioOutput { +impl

Default for AudioOutput

+where + P: Decodable, +{ fn default() -> Self { Self { device: rodio::default_output_device().unwrap(), @@ -20,18 +26,23 @@ impl Default for AudioOutput { } } -impl AudioOutput { - pub fn play_source(&self, audio_source: &AudioSource) { +impl

AudioOutput

+where + P: Decodable, +

::Decoder: rodio::Source + Send + Sync, + <

::Decoder as Iterator>::Item: rodio::Sample + Send + Sync, +{ + pub fn play_source(&self, audio_source: &P) { let sink = Sink::new(&self.device); - sink.append(Decoder::new(Cursor::new(audio_source.clone())).unwrap()); + sink.append(audio_source.decoder()); sink.detach(); } - pub fn play(&self, audio_source: Handle) { + pub fn play(&self, audio_source: Handle

) { self.queue.write().push_front(audio_source); } - pub fn try_play_queued(&self, audio_sources: &Assets) { + pub fn try_play_queued(&self, audio_sources: &Assets

) { let mut queue = self.queue.write(); let len = queue.len(); let mut i = 0; @@ -49,9 +60,11 @@ impl AudioOutput { } /// Plays audio currently queued in the [AudioOutput] resource -pub(crate) fn play_queued_audio_system( - audio_sources: Res>, - audio_output: Res, -) { +pub fn play_queued_audio_system

(audio_sources: Res>, audio_output: Res>) +where + P: Decodable, +

::Decoder: rodio::Source + Send + Sync, + <

::Decoder as Iterator>::Item: rodio::Sample + Send + Sync, +{ audio_output.try_play_queued(&audio_sources); } diff --git a/crates/bevy_audio/src/audio_source.rs b/crates/bevy_audio/src/audio_source.rs index 16a032e3ae31e..3635d802dcc59 100644 --- a/crates/bevy_audio/src/audio_source.rs +++ b/crates/bevy_audio/src/audio_source.rs @@ -1,6 +1,6 @@ use anyhow::Result; use bevy_asset::AssetLoader; -use std::{path::Path, sync::Arc}; +use std::{io::Cursor, path::Path, sync::Arc}; /// A source of audio data #[derive(Clone)] @@ -30,3 +30,17 @@ impl AssetLoader for Mp3Loader { EXTENSIONS } } + +pub trait Decodable: Send + Sync + 'static { + type Decoder; + + fn decoder(&self) -> Self::Decoder; +} + +impl Decodable for AudioSource { + type Decoder = rodio::Decoder>; + + fn decoder(&self) -> Self::Decoder { + rodio::Decoder::new(Cursor::new(self.clone())).unwrap() + } +} diff --git a/crates/bevy_audio/src/lib.rs b/crates/bevy_audio/src/lib.rs index 46270278f58da..945ba853f6000 100644 --- a/crates/bevy_audio/src/lib.rs +++ b/crates/bevy_audio/src/lib.rs @@ -5,7 +5,7 @@ pub use audio_output::*; pub use audio_source::*; pub mod prelude { - pub use crate::{AudioOutput, AudioSource}; + pub use crate::{AudioOutput, AudioSource, Decodable}; } use bevy_app::prelude::*; @@ -18,9 +18,12 @@ pub struct AudioPlugin; impl Plugin for AudioPlugin { fn build(&self, app: &mut AppBuilder) { - app.init_resource::() + app.init_resource::>() .add_asset::() .add_asset_loader::() - .add_system_to_stage(stage::POST_UPDATE, play_queued_audio_system.system()); + .add_system_to_stage( + stage::POST_UPDATE, + play_queued_audio_system::.system(), + ); } } diff --git a/examples/audio/audio.rs b/examples/audio/audio.rs index 21744477c8ce1..1be30281575d8 100644 --- a/examples/audio/audio.rs +++ b/examples/audio/audio.rs @@ -8,7 +8,7 @@ fn main() { .run(); } -fn setup(asset_server: Res, audio_output: Res) { +fn setup(asset_server: Res, audio_output: Res>) { let music = asset_server .load("assets/sounds/Windless Slopes.mp3") .unwrap(); From 0bad5b544d6b4d408b6bb6c4c626c49cf6ff5b0a Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Mon, 24 Aug 2020 19:40:04 -0700 Subject: [PATCH 2/2] use AudioSource as type for exported AudioOutput --- crates/bevy_audio/src/audio_output.rs | 4 ++-- examples/audio/audio.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_audio/src/audio_output.rs b/crates/bevy_audio/src/audio_output.rs index 42fdeabd1e234..d484e46b03da6 100644 --- a/crates/bevy_audio/src/audio_output.rs +++ b/crates/bevy_audio/src/audio_output.rs @@ -1,4 +1,4 @@ -use crate::Decodable; +use crate::{AudioSource, Decodable}; use bevy_asset::{Assets, Handle}; use bevy_ecs::Res; use parking_lot::RwLock; @@ -6,7 +6,7 @@ use rodio::{Device, Sink}; use std::collections::VecDeque; /// Used to play audio on the current "audio device" -pub struct AudioOutput

+pub struct AudioOutput

where P: Decodable, { diff --git a/examples/audio/audio.rs b/examples/audio/audio.rs index 1be30281575d8..21744477c8ce1 100644 --- a/examples/audio/audio.rs +++ b/examples/audio/audio.rs @@ -8,7 +8,7 @@ fn main() { .run(); } -fn setup(asset_server: Res, audio_output: Res>) { +fn setup(asset_server: Res, audio_output: Res) { let music = asset_server .load("assets/sounds/Windless Slopes.mp3") .unwrap();