1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
//! Audio plugin for the game engine Bevy //! //! It uses the library Kira to play audio and offers an API to control running game audio //! via Bevy's ECS. //! //! ```edition2018 //! # use bevy_kira_audio::{AudioChannel, Audio, AudioPlugin}; //! # use bevy::prelude::*; //! fn main() { //! let mut app = App::build(); //! app //! .add_plugins(DefaultPlugins) //! .add_plugin(AudioPlugin) //! .add_startup_system(start_background_audio.system()); //! app.run(); //! } //! //! fn start_background_audio(asset_server: Res<AssetServer>, audio: Res<Audio>) { //! audio.play_looped(asset_server.load("background_audio.mp3")); //! } //! ``` #![forbid(unsafe_code)] #![warn(unused_imports, missing_docs)] pub use audio::Audio; pub use channel::AudioChannel; pub use source::AudioSource; pub use stream::{AudioStream, Frame, StreamedAudio}; mod audio; mod audio_output; mod channel; mod source; mod stream; use crate::audio_output::{play_queued_audio_system, stream_audio_system, AudioOutput}; #[cfg(feature = "flac")] use crate::source::FlacLoader; #[cfg(feature = "mp3")] use crate::source::Mp3Loader; #[cfg(feature = "ogg")] use crate::source::OggLoader; #[cfg(feature = "wav")] use crate::source::WavLoader; use bevy::prelude::{AddAsset, AppBuilder, CoreStage, IntoExclusiveSystem, Plugin}; use std::marker::PhantomData; /// A Bevy plugin to add audio functionallity /// /// Add this plugin to your Bevy app to get access to /// the Audio resource /// ```edition2018 /// # use bevy_kira_audio::{AudioChannel, Audio, AudioPlugin}; /// # use bevy::prelude::*; /// fn main() { /// let mut app = App::build(); /// app /// .add_plugins(DefaultPlugins) /// .add_plugin(AudioPlugin) /// .add_startup_system(start_background_audio.system()); /// app.run(); /// } /// /// fn start_background_audio(asset_server: Res<AssetServer>, audio: Res<Audio>) { /// audio.play_looped(asset_server.load("background_audio.mp3")); /// } /// ``` #[derive(Default)] pub struct AudioPlugin; impl Plugin for AudioPlugin { fn build(&self, app: &mut AppBuilder) { app.init_non_send_resource::<AudioOutput>() .add_asset::<AudioSource>(); #[cfg(feature = "mp3")] app.init_asset_loader::<Mp3Loader>(); #[cfg(feature = "ogg")] app.init_asset_loader::<OggLoader>(); #[cfg(feature = "wav")] app.init_asset_loader::<WavLoader>(); #[cfg(feature = "flac")] app.init_asset_loader::<FlacLoader>(); app.init_resource::<Audio>().add_system_to_stage( CoreStage::PostUpdate, play_queued_audio_system.exclusive_system(), ); } } /// A Bevy plugin for streaming of audio /// /// This plugin requires [AudioPlugin] to also be active /// ```edition2018 /// # use bevy_kira_audio::{AudioStream, Frame, StreamedAudio, AudioChannel, Audio, AudioPlugin, AudioStreamPlugin}; /// # use bevy::prelude::*; /// fn main() { /// let mut app = App::build(); /// app /// .add_plugins(DefaultPlugins) /// .add_plugin(AudioPlugin) /// .add_plugin(AudioStreamPlugin::<SineStream>::default()) /// .add_startup_system(start_stream.system()); /// app.run(); /// } /// /// #[derive(Debug, Default)] /// struct SineStream { /// t: f64, /// note: f64, /// frequency: f64 /// } /// /// impl AudioStream for SineStream { /// fn next(&mut self, _: f64) -> Frame { /// let increment = 2.0 * std::f64::consts::PI * self.note / self.frequency; /// self.t += increment; /// /// let sample: f64 = self.t.sin(); /// Frame { /// left: sample as f32, /// right: sample as f32, /// } /// } /// } /// ///fn start_stream(audio: Res<StreamedAudio<SineStream>>) { /// audio.stream(SineStream { /// t: 0.0, /// note: 440.0, /// frequency: 44_000.0, /// }); ///} /// ``` #[derive(Default)] pub struct AudioStreamPlugin<T: AudioStream> { _marker: PhantomData<T>, } impl<T> Plugin for AudioStreamPlugin<T> where T: AudioStream, { fn build(&self, app: &mut AppBuilder) { app.init_resource::<StreamedAudio<T>>().add_system_to_stage( CoreStage::PostUpdate, stream_audio_system::<T>.exclusive_system(), ); } }