use crate::{Audio, AudioSource, Decodable}; use bevy_asset::{Asset, Assets}; use bevy_ecs::{Resources, World}; use rodio::{OutputStream, OutputStreamHandle, Sink}; use std::marker::PhantomData; /// Used internally to play audio on the current "audio device" pub struct AudioOutput
where P: Decodable, { _stream: OutputStream, stream_handle: OutputStreamHandle, phantom: PhantomData
, } impl
Default for AudioOutput
where P: Decodable, { fn default() -> Self { let (stream, stream_handle) = OutputStream::try_default().unwrap(); Self { _stream: stream, stream_handle, phantom: PhantomData, } } } impl
AudioOutput
where P: Asset + Decodable,
::Decoder: rodio::Source + Send + Sync, <
::Decoder as Iterator>::Item: rodio::Sample + Send + Sync, { fn play_source(&self, audio_source: &P) { let sink = Sink::try_new(&self.stream_handle).unwrap(); sink.append(audio_source.decoder()); sink.detach(); } fn try_play_queued(&self, audio_sources: &Assets
, audio: &mut Audio
) {
let mut queue = audio.queue.write();
let len = queue.len();
let mut i = 0;
while i < len {
let audio_source_handle = queue.pop_back().unwrap();
if let Some(audio_source) = audio_sources.get(&audio_source_handle) {
self.play_source(audio_source);
} else {
// audio source hasn't loaded yet. add it back to the queue
queue.push_front(audio_source_handle);
}
i += 1;
}
}
}
/// Plays audio currently queued in the [Audio] resource through the [AudioOutput] resource
pub fn play_queued_audio_system ::Decoder: rodio::Source + Send + Sync,
< ::Decoder as Iterator>::Item: rodio::Sample + Send + Sync,
{
let audio_output = resources.get_non_send::