use fmod_sys::*;
use lanyard::{Utf8CStr, Utf8CString};
use std::ffi::{c_float, c_int};
use crate::{Dsp, DspType};
use crate::{FmodResultExt, Result};
pub trait ReadableParameter: Sized {
fn get_parameter(dsp: Dsp, index: c_int) -> Result<Self>;
fn get_parameter_string(dsp: Dsp, index: c_int) -> Result<Utf8CString>;
}
pub trait WritableParameter: Sized {
fn set_parameter(self, dsp: Dsp, index: c_int) -> Result<()>;
}
impl ReadableParameter for bool {
fn get_parameter(dsp: Dsp, index: c_int) -> Result<Self> {
let dsp = dsp.inner.as_ptr();
unsafe {
let mut value = FMOD_BOOL::FALSE;
FMOD_DSP_GetParameterBool(dsp, index, &raw mut value, std::ptr::null_mut(), 0)
.to_result()?;
Ok(value.into())
}
}
fn get_parameter_string(dsp: Dsp, index: c_int) -> Result<Utf8CString> {
let dsp = dsp.inner.as_ptr();
let mut bytes = [0; FMOD_DSP_GETPARAM_VALUESTR_LENGTH as usize];
unsafe {
FMOD_DSP_GetParameterBool(
dsp,
index,
std::ptr::null_mut(),
bytes.as_mut_ptr().cast(),
FMOD_DSP_GETPARAM_VALUESTR_LENGTH as i32,
)
.to_result()?;
let string = Utf8CStr::from_utf8_until_nul(&bytes).unwrap().to_cstring();
Ok(string)
}
}
}
impl WritableParameter for bool {
fn set_parameter(self, dsp: Dsp, index: c_int) -> Result<()> {
let dsp = dsp.inner.as_ptr();
unsafe { FMOD_DSP_SetParameterBool(dsp, index, self.into()).to_result() }
}
}
impl ReadableParameter for c_int {
fn get_parameter(dsp: Dsp, index: c_int) -> Result<Self> {
let dsp = dsp.inner.as_ptr();
unsafe {
let mut value = 0;
FMOD_DSP_GetParameterInt(dsp, index, &raw mut value, std::ptr::null_mut(), 0)
.to_result()?;
Ok(value)
}
}
fn get_parameter_string(dsp: Dsp, index: c_int) -> Result<Utf8CString> {
let dsp = dsp.inner.as_ptr();
let mut bytes = [0; FMOD_DSP_GETPARAM_VALUESTR_LENGTH as usize];
unsafe {
FMOD_DSP_GetParameterInt(
dsp,
index,
std::ptr::null_mut(),
bytes.as_mut_ptr().cast(),
FMOD_DSP_GETPARAM_VALUESTR_LENGTH as i32,
)
.to_result()?;
let string = Utf8CStr::from_utf8_until_nul(&bytes).unwrap().to_cstring();
Ok(string)
}
}
}
impl WritableParameter for c_int {
fn set_parameter(self, dsp: Dsp, index: c_int) -> Result<()> {
let dsp = dsp.inner.as_ptr();
unsafe { FMOD_DSP_SetParameterInt(dsp, index, self).to_result() }
}
}
impl ReadableParameter for c_float {
fn get_parameter(dsp: Dsp, index: c_int) -> Result<Self> {
let dsp = dsp.inner.as_ptr();
unsafe {
let mut value = 0.0;
FMOD_DSP_GetParameterFloat(dsp, index, &raw mut value, std::ptr::null_mut(), 0)
.to_result()?;
Ok(value)
}
}
fn get_parameter_string(dsp: Dsp, index: c_int) -> Result<Utf8CString> {
let dsp = dsp.inner.as_ptr();
let mut bytes = [0; FMOD_DSP_GETPARAM_VALUESTR_LENGTH as usize];
unsafe {
FMOD_DSP_GetParameterFloat(
dsp,
index,
std::ptr::null_mut(),
bytes.as_mut_ptr().cast(),
FMOD_DSP_GETPARAM_VALUESTR_LENGTH as i32,
)
.to_result()?;
let string = Utf8CStr::from_utf8_until_nul(&bytes).unwrap().to_cstring();
Ok(string)
}
}
}
impl WritableParameter for c_float {
fn set_parameter(self, dsp: Dsp, index: c_int) -> Result<()> {
let dsp = dsp.inner.as_ptr();
unsafe { FMOD_DSP_SetParameterFloat(dsp, index, self).to_result() }
}
}
pub trait ReadableParameterIndex<T> {
const TYPE: DspType;
fn into_index(self) -> c_int;
}
impl<T> ReadableParameterIndex<T> for c_int {
const TYPE: DspType = DspType::Unknown;
fn into_index(self) -> c_int {
self
}
}
pub trait WritableParameterIndex<T> {
const TYPE: DspType;
fn into_index(self) -> c_int;
}
impl<T> WritableParameterIndex<T> for c_int {
const TYPE: DspType = DspType::Unknown;
fn into_index(self) -> c_int {
self
}
}