use kira::{Decibels, Panning, sound::Region};
use crate::Context;
pub struct AudioContext<'path, 'ctx> {
pub(crate) path: &'path str,
pub(crate) ctx: &'ctx Context,
pub(crate) volume: Option<f32>,
pub(crate) panning: Option<f32>,
pub(crate) loop_region: Option<Region>,
pub(crate) playback_region: Option<Region>,
}
impl AudioContext<'_, '_> {
#[inline(always)]
#[must_use]
pub const fn with_volume(mut self, volume: f32) -> Self {
self.volume = Some(volume);
self
}
#[inline(always)]
#[must_use]
pub const fn pan(mut self, panning: f32) -> Self {
self.panning = Some(panning);
self
}
#[inline(always)]
#[must_use]
pub fn with_loop(mut self) -> Self {
self.loop_region = Some((..).into());
self
}
#[inline(always)]
#[must_use]
pub fn with_loop_region(mut self, loop_region: impl Into<Region>) -> Self {
self.loop_region = Some(loop_region.into());
self
}
#[inline(always)]
#[must_use]
pub fn with_playback_region(mut self, playback_region: impl Into<Region>) -> Self {
self.playback_region = Some(playback_region.into());
self
}
#[inline(always)]
pub fn play(self) {
self.ctx.write(|ctx| {
let sound_data = &ctx.audio(self.path).0;
let mut settings = sound_data.settings;
if let Some(volume) = self.volume {
settings = settings.volume(Decibels::from(volume));
}
if let Some(panning) = self.panning {
settings = settings.panning(Panning::from(panning));
}
if let Some(loop_region) = self.loop_region {
settings = settings.loop_region(loop_region);
}
let mut sound_data = sound_data.with_settings(settings);
if let Some(playback_region) = self.playback_region {
sound_data = sound_data.slice(playback_region);
}
ctx.audio_manager
.play(sound_data)
.expect("Error playing audio");
});
}
}
impl Context {
#[inline(always)]
#[must_use]
pub const fn audio<'path>(&self, path: &'path str) -> AudioContext<'path, '_> {
AudioContext {
path,
ctx: self,
volume: None,
panning: None,
loop_region: None,
playback_region: None,
}
}
}