1use std;
2use std::rc::Rc;
3use std::ops::{Deref, DerefMut};
4use log;
5use num_derive::FromPrimitive;
6use crate::{ll, fmod_result, reverb3d, Channelmask, Error, Speakermode, System};
7
8pub mod parameter;
9
10pub use parameter::{Echo, Lowpass, MultibandEq, MultibandEqFilterType,
11 Sfxreverb};
12
13pub const GETPARAM_VALUESTR_LENGTH : u32 = ll::FMOD_DSP_GETPARAM_VALUESTR_LENGTH;
19pub const REVERB_MAXINSTANCES : u32 = ll::FMOD_REVERB_MAXINSTANCES;
25
26#[derive(Clone, Debug, PartialEq)]
27pub struct Dsp {
28 inner : Rc <Inner>,
29 system : System
30}
31
32#[derive(Clone, Debug, PartialEq)]
33pub struct DspRef {
34 pub (crate) dsp : Dsp
35}
36
37#[derive(PartialEq)]
38struct Inner {
39 raw : *mut ll::FMOD_DSP,
40 owned : bool
41}
42
43pub struct State {
45 pub instance : *const std::ffi::c_void,
46 pub plugindata : Vec <u8>,
47 pub channelmask : Channelmask,
48 pub source_speakermode : Speakermode,
49 pub sidechaindata : *const std::ffi::c_void,
50 pub sidechainchannels : i32,
51 pub functions : StateFunctions,
52 pub systemobject : i32
53}
54
55pub struct StateFunctions {
57 pub alloc : ll::FMOD_DSP_ALLOC_FUNC,
58 pub realloc : ll::FMOD_DSP_REALLOC_FUNC,
59 pub free : ll::FMOD_DSP_FREE_FUNC,
60 pub getsamplerate : ll::FMOD_DSP_GETSAMPLERATE_FUNC,
61 pub getblocksize : ll::FMOD_DSP_GETBLOCKSIZE_FUNC,
62 pub dft : StateDftFunctions,
63 pub pan : StatePanFunctions,
64 pub getspeakermode : ll::FMOD_DSP_GETSPEAKERMODE_FUNC,
65 pub getclock : ll::FMOD_DSP_GETCLOCK_FUNC,
66 pub getlistenerattributes : ll::FMOD_DSP_GETLISTENERATTRIBUTES_FUNC,
67 pub log : ll::FMOD_DSP_LOG_FUNC,
68 pub getuserdata : ll::FMOD_DSP_GETUSERDATA_FUNC
69}
70
71pub struct StateDftFunctions {
73 pub fftreal : ll::FMOD_DSP_DFT_FFTREAL_FUNC,
74 pub inversefftreal : ll::FMOD_DSP_DFT_IFFTREAL_FUNC,
75}
76
77pub struct StatePanFunctions {
79 pub summonomatrix : ll::FMOD_DSP_PAN_SUMMONOMATRIX_FUNC,
80 pub sumstereomatrix : ll::FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC,
81 pub sumsurroundmatrix : ll::FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC,
82 pub summonotosurroundmatrix : ll::FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC,
83 pub sumstereotosurroundmatrix : ll::FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC,
84 pub getrolloffgain : ll::FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC,
85}
86
87pub struct Description {
89 pub pluginsdkversion : u32,
90 pub name : String,
91 pub version : u32,
92 pub numinputbuffers : i32,
93 pub numoutputbuffers : i32,
94 pub numparameters : i32,
95 pub paramdesc : parameter::Desc,
96 pub userdata : Vec <u8>,
97 pub create : ll::FMOD_DSP_CREATE_CALLBACK,
98 pub release : ll::FMOD_DSP_RELEASE_CALLBACK,
99 pub reset : ll::FMOD_DSP_RESET_CALLBACK,
100 pub read : ll::FMOD_DSP_READ_CALLBACK,
101 pub process : ll::FMOD_DSP_PROCESS_CALLBACK,
102 pub setposition : ll::FMOD_DSP_SETPOSITION_CALLBACK,
103 pub setparameterfloat : ll::FMOD_DSP_SETPARAM_FLOAT_CALLBACK,
104 pub setparameterint : ll::FMOD_DSP_SETPARAM_INT_CALLBACK,
105 pub setparameterbool : ll::FMOD_DSP_SETPARAM_BOOL_CALLBACK,
106 pub setparameterdata : ll::FMOD_DSP_SETPARAM_DATA_CALLBACK,
107 pub getparameterfloat : ll::FMOD_DSP_GETPARAM_FLOAT_CALLBACK,
108 pub getparameterint : ll::FMOD_DSP_GETPARAM_INT_CALLBACK,
109 pub getparameterbool : ll::FMOD_DSP_GETPARAM_BOOL_CALLBACK,
110 pub getparameterdata : ll::FMOD_DSP_GETPARAM_DATA_CALLBACK,
111 pub shouldiprocess : ll::FMOD_DSP_SHOULDIPROCESS_CALLBACK,
112 pub sys_register : ll::FMOD_DSP_SYSTEM_REGISTER_CALLBACK,
113 pub sys_deregister : ll::FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK,
114 pub sys_mix : ll::FMOD_DSP_SYSTEM_MIX_CALLBACK,
115 ll : ll::FMOD_DSP_DESCRIPTION
116}
117
118#[derive(Copy, Clone, Debug, Eq, PartialEq, FromPrimitive)]
119pub enum Type {
120 Unknown = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_UNKNOWN as isize,
121 Mixer = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_MIXER as isize,
122 Oscillator = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_OSCILLATOR as isize,
123 Lowpass = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_LOWPASS as isize,
124 Itlowpass = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_ITLOWPASS as isize,
125 Highpass = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_HIGHPASS as isize,
126 Echo = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_ECHO as isize,
127 Fader = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_FADER as isize,
128 Flange = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_FLANGE as isize,
129 Distortion = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_DISTORTION as isize,
130 Normalize = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_NORMALIZE as isize,
131 Limiter = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_LIMITER as isize,
132 Parameq = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_PARAMEQ as isize,
133 Pitchshift = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_PITCHSHIFT as isize,
134 Chorus = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_CHORUS as isize,
135 Vstplugin = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_VSTPLUGIN as isize,
136 Winampplugin = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_WINAMPPLUGIN as isize,
137 Itecho = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_ITECHO as isize,
138 Compressor = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_COMPRESSOR as isize,
139 Sfxreverb = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_SFXREVERB as isize,
140 LowpassSimple = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_LOWPASS_SIMPLE as isize,
141 Delay = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_DELAY as isize,
142 Tremolo = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_TREMOLO as isize,
143 Ladspaplugin = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_LADSPAPLUGIN as isize,
144 Send = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_SEND as isize,
145 Return = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_RETURN as isize,
146 HighpassSimple = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_HIGHPASS_SIMPLE as isize,
147 Pan = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_PAN as isize,
148 ThreeEq = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_THREE_EQ as isize,
149 FFT = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_FFT as isize,
150 LoudnessMeter = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_LOUDNESS_METER as isize,
151 Envelopefollower = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_ENVELOPEFOLLOWER as isize,
152 Convolutionreverb = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_CONVOLUTIONREVERB as isize,
153 Channelmix = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_CHANNELMIX as isize,
154 Transceiver = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_TRANSCEIVER as isize,
155 Objectpan = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_OBJECTPAN as isize,
156 MultibandEq = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_MULTIBAND_EQ as isize,
157 MAX = ll::FMOD_DSP_TYPE_FMOD_DSP_TYPE_MAX as isize
158}
159
160impl Dsp {
161 #[inline]
162 pub fn from_raw_parts (raw : *mut ll::FMOD_DSP, owned : bool, system : System)
163 -> Self
164 {
165 let inner = Rc::new (Inner { raw, owned });
166 Dsp { inner, system }
167 }
168
169 #[inline]
170 pub fn raw (&self) -> *mut ll::FMOD_DSP {
171 self.inner.raw
172 }
173
174 #[inline]
175 pub fn dsp_ref (&self) -> DspRef {
176 let dsp = {
177 let inner = Rc::new (Inner {
178 raw: self.raw(),
179 owned: false
180 });
181 let system = self.system.clone();
182 Dsp { inner, system }
183 };
184 DspRef { dsp }
185 }
186
187 #[inline]
188 pub fn get_active (&self) -> Result <bool, Error> {
189 let mut active = 0;
190 unsafe {
191 fmod_result!(ll::FMOD_DSP_GetActive (self.raw(), &mut active))?;
192 }
193 Ok (active != 0)
194 }
195
196 #[inline]
197 pub fn get_bypass (&self) -> Result <bool, Error> {
198 let mut bypass = 0;
199 unsafe {
200 fmod_result!(ll::FMOD_DSP_GetBypass (self.raw(), &mut bypass))?;
201 }
202 Ok (bypass != 0)
203 }
204
205 #[inline]
206 pub fn get_num_inputs (&self) -> Result <i32, Error> {
207 let mut numinputs = 0;
208 unsafe {
209 fmod_result!(ll::FMOD_DSP_GetNumInputs (self.raw(), &mut numinputs))?;
210 }
211 Ok (numinputs)
212 }
213
214 #[inline]
215 pub fn get_num_outputs (&self) -> Result <i32, Error> {
216 let mut numoutputs = 0;
217 unsafe {
218 fmod_result!(ll::FMOD_DSP_GetNumOutputs (self.raw(), &mut numoutputs))?;
219 }
220 Ok (numoutputs)
221 }
222
223 #[inline]
224 pub fn get_parameter_float (&mut self, index : i32)
225 -> Result <f32, Error>
226 {
227 let mut value = 0.0;
228 unsafe {
229 fmod_result!(
230 ll::FMOD_DSP_GetParameterFloat (
231 self.raw(), index, &mut value, std::ptr::null_mut(), 0)
232 )?;
233 }
234 Ok (value)
235 }
236
237 #[inline]
240 pub fn get_parameter_float_description (&mut self, index : i32)
241 -> Result <(f32, String), Error>
242 {
243 let mut value = 0.0;
244 const VALUESTRLEN : i32 = 33;
247 let mut valuestr = vec![0; VALUESTRLEN as usize];
248 unsafe {
249 fmod_result!(
250 ll::FMOD_DSP_GetParameterFloat (
251 self.raw(),
252 index,
253 &mut value,
254 valuestr.as_mut_ptr() as *mut i8,
255 VALUESTRLEN
256 ))?;
257 }
258 valuestr.retain (|c| *c != 0x0);
259 let description = String::from_utf8 (valuestr).map_err (|e|{
260 log::error!("dsp get parameter description string invalid utf8: {e}");
261 Error::InvalidString
262 })?;
263 Ok ((value, description))
264 }
265
266 #[inline]
267 pub fn get_type (&self) -> Result <Type, Error> {
268 let mut type_ = 0;
269 unsafe {
270 fmod_result!(ll::FMOD_DSP_GetType (self.raw(), &mut type_))?;
271 }
272 Ok (Type::from_ll (type_))
273 }
274
275 #[inline]
276 pub fn set_active (&mut self, active : bool) -> Result <(), Error> {
277 unsafe {
278 fmod_result!(ll::FMOD_DSP_SetActive (self.raw(), active as i32))
279 }
280 }
281
282 #[inline]
283 pub fn set_bypass (&mut self, bypass : bool) -> Result <(), Error> {
284 unsafe {
285 fmod_result!(ll::FMOD_DSP_SetBypass (self.raw(), bypass as i32))
286 }
287 }
288
289 #[inline]
290 pub fn set_parameter_float (&mut self, index : i32, value : f32)
291 -> Result <(), Error>
292 {
293 unsafe {
294 fmod_result!(ll::FMOD_DSP_SetParameterFloat (self.raw(), index, value))
295 }
296 }
297
298 #[inline]
299 pub fn set_parameter_int (&mut self, index : i32, value : i32)
300 -> Result <(), Error>
301 {
302 unsafe {
303 fmod_result!(ll::FMOD_DSP_SetParameterInt (self.raw(), index, value))
304 }
305 }
306
307 pub fn get_parameters_sfxreverb (&mut self)
314 -> Result <(reverb3d::Properties, f32), Error>
315 {
316 assert_eq!(self.get_type()?, Type::Sfxreverb);
317 let properties = reverb3d::Properties {
318 decay_time: self.get_parameter_float (Sfxreverb::DecayTime as i32)?,
319 early_delay: self.get_parameter_float (Sfxreverb::EarlyDelay as i32)?,
320 late_delay: self.get_parameter_float (Sfxreverb::LateDelay as i32)?,
321 hf_reference: self.get_parameter_float (Sfxreverb::HfReference as i32)?,
322 hf_decay_ratio: self.get_parameter_float (Sfxreverb::HfDecayRatio as i32)?,
323 diffusion: self.get_parameter_float (Sfxreverb::Diffusion as i32)?,
324 density: self.get_parameter_float (Sfxreverb::Density as i32)?,
325 low_shelf_frequency:
326 self.get_parameter_float (Sfxreverb::LowShelfFrequency as i32)?,
327 low_shelf_gain: self.get_parameter_float (Sfxreverb::LowShelfGain as i32)?,
328 high_cut: self.get_parameter_float (Sfxreverb::HighCut as i32)?,
329 early_late_mix: self.get_parameter_float (Sfxreverb::EarlyLateMix as i32)?,
330 wet_level: self.get_parameter_float (Sfxreverb::WetLevel as i32)?
331 };
332 let dry_level = self.get_parameter_float (Sfxreverb::DryLevel as i32)?;
333 Ok ((properties, dry_level))
334 }
335
336 pub fn set_parameters_sfxreverb (&mut self,
343 properties : &reverb3d::Properties,
344 dry_level : f32
345 ) -> Result <(), Error> {
346 assert_eq!(self.get_type()?, Type::Sfxreverb);
347 self.set_parameter_float (
348 Sfxreverb::DecayTime as i32, properties.decay_time)?;
349 self.set_parameter_float (
350 Sfxreverb::EarlyDelay as i32, properties.early_delay)?;
351 self.set_parameter_float (
352 Sfxreverb::LateDelay as i32, properties.late_delay)?;
353 self.set_parameter_float (
354 Sfxreverb::HfReference as i32, properties.hf_reference)?;
355 self.set_parameter_float (
356 Sfxreverb::HfDecayRatio as i32, properties.hf_decay_ratio)?;
357 self.set_parameter_float (
358 Sfxreverb::Diffusion as i32, properties.diffusion)?;
359 self.set_parameter_float (
360 Sfxreverb::Density as i32, properties.density)?;
361 self.set_parameter_float (
362 Sfxreverb::LowShelfFrequency as i32, properties.low_shelf_frequency)?;
363 self.set_parameter_float (
364 Sfxreverb::LowShelfGain as i32, properties.low_shelf_gain)?;
365 self.set_parameter_float (
366 Sfxreverb::HighCut as i32, properties.high_cut)?;
367 self.set_parameter_float (
368 Sfxreverb::EarlyLateMix as i32, properties.early_late_mix)?;
369 self.set_parameter_float (
370 Sfxreverb::WetLevel as i32, properties.wet_level)?;
371 self.set_parameter_float (
372 Sfxreverb::DryLevel as i32, dry_level)?;
373 Ok (())
374 }
375}
376
377impl Deref for DspRef {
378 type Target = Dsp;
379 fn deref (&self) -> &Dsp {
380 &self.dsp
381 }
382}
383
384impl DerefMut for DspRef {
385 fn deref_mut (&mut self) -> &mut Dsp {
386 &mut self.dsp
387 }
388}
389
390impl Type {
391 pub fn from_ll (ll : ll::FMOD_DSP_TYPE) -> Self {
395 use num_traits::FromPrimitive;
396 #[allow(clippy::allow_attributes, clippy::unnecessary_cast)]
398 Self::from_u32 (ll as u32).unwrap()
399 }
400}
401
402impl AsRef <ll::FMOD_DSP_DESCRIPTION> for Description {
403 fn as_ref (&self) -> &ll::FMOD_DSP_DESCRIPTION {
404 &self.ll
405 }
406}
407
408impl std::fmt::Debug for Inner {
409 fn fmt (&self, f : &mut std::fmt::Formatter) -> std::fmt::Result {
410 write!(f, "Inner {{ raw: {:p}, owned: {} }}", self.raw, self.owned)
411 }
412}
413
414impl Drop for Inner {
415 fn drop (&mut self) {
416 if self.owned {
417 unsafe {
418 let _ = fmod_result!(ll::FMOD_DSP_Release (self.raw)).map_err (
419 |err| log::error!("error releasing FMOD DSP@{self:?}: {err:?}"));
420 }
421 }
422 }
423}