use std::{self, rc::Rc};
use log;
use crate::{ll, fmod_result, vector, Error, System};
#[derive(Clone, Debug, PartialEq)]
pub struct Reverb3d {
inner : Rc <Inner>,
system : System
}
#[derive(PartialEq)]
struct Inner (*mut ll::FMOD_REVERB3D);
#[derive(Clone, Debug, PartialEq)]
pub struct Attributes {
pub position : [f32; 3],
pub mindistance : f32,
pub maxdistance : f32
}
pub mod presets;
pub use presets::*;
#[derive(Clone, Debug, PartialEq)]
pub struct Properties {
pub decay_time : f32,
pub early_delay : f32,
pub late_delay : f32,
pub hf_reference : f32,
pub hf_decay_ratio : f32,
pub diffusion : f32,
pub density : f32,
pub low_shelf_frequency : f32,
pub low_shelf_gain : f32,
pub high_cut : f32,
pub early_late_mix : f32,
pub wet_level : f32
}
impl Reverb3d {
#[inline]
pub fn from_raw_parts (raw : *mut ll::FMOD_REVERB3D, system : System)
-> Self
{
let inner = Rc::new (Inner (raw));
Reverb3d { inner, system }
}
#[inline]
fn raw (&self) -> *mut ll::FMOD_REVERB3D {
self.inner.0
}
#[inline]
pub fn get_3d_attributes (&self) -> Result <Attributes, Error> {
let mut position = vector::to_ll ([0.0; 3]);
let mut mindistance = 0.0;
let mut maxdistance = 0.0;
unsafe {
fmod_result!(ll::FMOD_Reverb3D_Get3DAttributes (self.raw(),
&mut position, &mut mindistance, &mut maxdistance
))?;
}
let attributes = Attributes {
position: [position.x, position.y, position.z],
mindistance,
maxdistance
};
Ok (attributes)
}
#[inline]
pub fn get_active (&self) -> Result <bool, Error> {
let mut active = 0;
unsafe {
fmod_result!(ll::FMOD_Reverb3D_GetActive (self.raw(), &mut active))?;
}
Ok (active != 0)
}
#[inline]
pub fn get_properties (&self) -> Result <Properties, Error> {
let mut properties = ll::FMOD_REVERB_PROPERTIES {
DecayTime: 0.0,
EarlyDelay: 0.0,
LateDelay: 0.0,
HFReference: 0.0,
HFDecayRatio: 0.0,
Diffusion: 0.0,
Density: 0.0,
LowShelfFrequency: 0.0,
LowShelfGain: 0.0,
HighCut: 0.0,
EarlyLateMix: 0.0,
WetLevel: 0.0
};
unsafe {
fmod_result!(
ll::FMOD_Reverb3D_GetProperties (self.raw(), &mut properties)
)?;
}
let properties = Properties::from_ll (&properties);
Ok (properties)
}
}
impl Properties {
#[inline]
pub const fn from_ll (properties : &ll::FMOD_REVERB_PROPERTIES) -> Self {
Properties {
decay_time: properties.DecayTime,
early_delay: properties.EarlyDelay,
late_delay: properties.LateDelay,
hf_reference: properties.HFReference,
hf_decay_ratio: properties.HFDecayRatio,
diffusion: properties.Diffusion,
density: properties.Density,
low_shelf_frequency: properties.LowShelfFrequency,
low_shelf_gain: properties.LowShelfGain,
high_cut: properties.HighCut,
early_late_mix: properties.EarlyLateMix,
wet_level: properties.WetLevel
}
}
#[inline]
pub const fn to_ll (&self) -> ll::FMOD_REVERB_PROPERTIES {
ll::FMOD_REVERB_PROPERTIES {
DecayTime: self.decay_time,
EarlyDelay: self.early_delay,
LateDelay: self.late_delay,
HFReference: self.hf_reference,
HFDecayRatio: self.hf_decay_ratio,
Diffusion: self.diffusion,
Density: self.density,
LowShelfFrequency: self.low_shelf_frequency,
LowShelfGain: self.low_shelf_gain,
HighCut: self.high_cut,
EarlyLateMix: self.early_late_mix,
WetLevel: self.wet_level
}
}
}
impl Default for Properties {
fn default() -> Self {
GENERIC.clone()
}
}
impl std::fmt::Debug for Inner {
fn fmt (&self, f : &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:p}", self.0)
}
}
impl Drop for Inner {
fn drop (&mut self) {
unsafe {
let _ = fmod_result!(ll::FMOD_Reverb3D_Release (self.0)).map_err (
|err| log::error!("error releasing FMOD Reverb3D@{:p}: {:?}", self.0, err));
}
}
}