use std::collections::HashMap;
use std::fmt;
use std::sync::Arc;
use crate::asset::AssetSource;
#[derive(Clone, Debug)]
pub enum AudioData {
#[cfg(feature = "registry")]
Embedded(oxideav_core::AudioFrame),
Source(Arc<dyn AssetSource>),
External { uri: String, mime: Option<String> },
}
#[derive(Clone)]
pub struct AudioSource {
pub name: Option<String>,
pub data: AudioData,
pub extras: HashMap<String, serde_json::Value>,
}
impl AudioSource {
pub fn from_uri(uri: impl Into<String>) -> Self {
Self {
name: None,
data: AudioData::External {
uri: uri.into(),
mime: None,
},
extras: HashMap::new(),
}
}
pub fn from_source(source: Arc<dyn AssetSource>) -> Self {
Self {
name: None,
data: AudioData::Source(source),
extras: HashMap::new(),
}
}
pub fn with_name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
}
impl fmt::Debug for AudioSource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AudioSource")
.field("name", &self.name)
.field("data", &self.data)
.field("extras", &self.extras)
.finish()
}
}
#[derive(Clone, Debug)]
pub struct AudioEmitter {
pub name: Option<String>,
pub source: AudioSourceId,
pub gain: f32,
pub looping: bool,
pub auto_play: bool,
pub spatial: Option<SpatialAudio>,
pub extras: HashMap<String, serde_json::Value>,
}
impl AudioEmitter {
pub fn new(source: AudioSourceId) -> Self {
Self {
name: None,
source,
gain: 1.0,
looping: false,
auto_play: false,
spatial: None,
extras: HashMap::new(),
}
}
pub fn with_name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn with_spatial(mut self, spatial: SpatialAudio) -> Self {
self.spatial = Some(spatial);
self
}
}
#[derive(Clone, Copy, Debug)]
pub struct SpatialAudio {
pub aural_mode: AuralMode,
pub cone_inner_angle: f32,
pub cone_outer_angle: f32,
pub cone_outer_gain: f32,
pub min_distance: f32,
pub max_distance: f32,
pub rolloff_factor: f32,
pub distance_model: DistanceModel,
}
impl Default for SpatialAudio {
fn default() -> Self {
let two_pi = std::f32::consts::TAU;
Self {
aural_mode: AuralMode::SpatialNonAcoustic,
cone_inner_angle: two_pi,
cone_outer_angle: two_pi,
cone_outer_gain: 0.0,
min_distance: 1.0,
max_distance: 10000.0,
rolloff_factor: 1.0,
distance_model: DistanceModel::Inverse,
}
}
}
impl SpatialAudio {
pub fn new() -> Self {
Self::default()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AuralMode {
SpatialNonAcoustic,
SpatialAcoustic,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DistanceModel {
Linear,
Inverse,
Exponential,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AudioSourceId(pub u32);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AudioEmitterId(pub u32);