fmod1 0.1.0

Rust wrapper for FMOD low-level API
Documentation
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);

/// 3D attributes
#[derive(Clone, Debug, PartialEq)]
pub struct Attributes {
  pub position    : [f32; 3],
  pub mindistance : f32,
  pub maxdistance : f32
}

pub mod presets;
pub use presets::*;

/// Attributes describing a I3DL2 compliant reverb environment.
///
/// These properties are also used to specify the global "ambient" reverb
/// properties of the system reverb instances (`System::set_reverb_properties`).
///
/// See also `dsp::Sfxreverb` which defines parameters for all these properties
/// with an additional *dry level* parameter.
#[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));
    }
  }
}