fmod/core/dsp/
general.rs

1// Copyright (c) 2024 Lily Lyons
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7use fmod_sys::*;
8use std::ffi::{c_uint, c_void};
9
10use crate::{Dsp, DspType, System};
11
12impl Dsp {
13    // TODO show dialogue config
14
15    /// Reset a DSPs internal state ready for new input signal.
16    ///
17    /// This will clear all internal state derived from input signal while retaining any set parameter values.
18    /// The intended use of the function is to avoid audible artifacts if moving the [`Dsp`] from one part of the [`Dsp`] network to another.
19    pub fn reset(&self) -> Result<()> {
20        unsafe { FMOD_DSP_Reset(self.inner).to_result() }
21    }
22
23    /// Frees a [`Dsp`] object.
24    ///
25    /// If [`Dsp`] is not removed from the network with ChannelControl::removeDSP after being added with ChannelControl::addDSP,
26    /// it will not release and will instead return [`FMOD_RESULT::FMOD_ERR_DSP_INUSE`].
27    pub fn release(self) -> Result<()> {
28        // release userdata
29        #[cfg(feature = "userdata-abstraction")]
30        let userdata = self.get_raw_userdata()?;
31
32        unsafe {
33            FMOD_DSP_Release(self.inner).to_result()?;
34        }
35
36        // release/remove userdata if it is not null
37        #[cfg(feature = "userdata-abstraction")]
38        if !userdata.is_null() {
39            crate::userdata::remove_userdata(userdata.into());
40            self.set_raw_userdata(std::ptr::null_mut())?;
41        }
42
43        Ok(())
44    }
45
46    /// Retrieves the pre-defined type of a FMOD registered [`Dsp`] unit.
47    pub fn get_type(&self) -> Result<DspType> {
48        let mut dsp_type = 0;
49        unsafe { FMOD_DSP_GetType(self.inner, &mut dsp_type).to_result()? };
50        let dsp_type = dsp_type.try_into()?;
51        Ok(dsp_type)
52    }
53
54    // TODO getinfo
55
56    /// Retrieves statistics on the mixer thread CPU usage for this unit.
57    ///
58    /// [`crate::InitFlags::PROFILE_ENABLE`] with [`crate::SystemBuilder::new`] is required to call this function.
59    pub fn get_cpu_usage(&self) -> Result<(c_uint, c_uint)> {
60        let mut exclusive = 0;
61        let mut inclusive = 0;
62        unsafe {
63            FMOD_DSP_GetCPUUsage(self.inner, &mut exclusive, &mut inclusive).to_result()?;
64        }
65        Ok((exclusive, inclusive))
66    }
67
68    #[allow(clippy::not_unsafe_ptr_arg_deref)] // fmod doesn't dereference the passed in pointer, and the user dereferencing it is unsafe anyway
69    pub fn set_raw_userdata(&self, userdata: *mut c_void) -> Result<()> {
70        unsafe { FMOD_DSP_SetUserData(self.inner, userdata).to_result() }
71    }
72
73    pub fn get_raw_userdata(&self) -> Result<*mut c_void> {
74        let mut userdata = std::ptr::null_mut();
75        unsafe {
76            FMOD_DSP_GetUserData(self.inner, &mut userdata).to_result()?;
77        }
78        Ok(userdata)
79    }
80
81    // TODO callback
82
83    /// Retrieves the parent System object.
84    pub fn get_system(&self) -> Result<System> {
85        let mut system = std::ptr::null_mut();
86        unsafe { FMOD_DSP_GetSystemObject(self.inner, &mut system).to_result()? };
87        Ok(system.into())
88    }
89}
90
91#[cfg(feature = "userdata-abstraction")]
92impl Dsp {
93    pub fn set_userdata(&self, userdata: crate::userdata::Userdata) -> Result<()> {
94        use crate::userdata::{insert_userdata, set_userdata};
95
96        let pointer = self.get_raw_userdata()?;
97        if pointer.is_null() {
98            let key = insert_userdata(userdata, *self);
99            self.set_raw_userdata(key.into())?;
100        } else {
101            set_userdata(pointer.into(), userdata);
102        }
103
104        Ok(())
105    }
106
107    pub fn get_userdata(&self) -> Result<Option<crate::userdata::Userdata>> {
108        use crate::userdata::get_userdata;
109
110        let pointer = self.get_raw_userdata()?;
111        Ok(get_userdata(pointer.into()))
112    }
113}