fmod/core/dsp/
parameters.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_float, c_int, c_uint};
9
10use crate::{Dsp, DspParameterDataType, DspParameterDescription};
11
12impl Dsp {
13    /// Retrieve the index of the first data parameter of a particular data type.
14    ///
15    /// This function returns [`Ok`] if a parmeter of matching type is found and [`FMOD_RESULT::FMOD_ERR_INVALID_PARAM`] if no matches were found.
16    ///
17    /// The return code can be used to check whether the [`Dsp`] supports specific functionality through data parameters of certain types without the need to provide index.
18    pub fn get_data_parameter_index(&self, data_type: DspParameterDataType) -> Result<c_int> {
19        let mut index = 0;
20        unsafe {
21            FMOD_DSP_GetDataParameterIndex(self.inner, data_type.into(), &mut index).to_result()?;
22        }
23        Ok(index)
24    }
25
26    /// Retrieves the number of parameters exposed by this unit.
27    ///
28    /// Use this to enumerate all parameters of a [`Dsp`] unit with [`Dsp::get_parameter_info`].
29    pub fn get_parameter_count(&self) -> Result<c_int> {
30        let mut count = 0;
31        unsafe { FMOD_DSP_GetNumParameters(self.inner, &mut count).to_result()? };
32        Ok(count)
33    }
34
35    /// Sets a boolean parameter by index.
36    pub fn set_parameter_bool(&self, index: c_int, value: bool) -> Result<()> {
37        unsafe { FMOD_DSP_SetParameterBool(self.inner, index, value.into()).to_result() }
38    }
39
40    /// Retrieves a boolean parameter by index.
41    ///
42    /// Note: FMOD also returns a string representation of the parameter value, but this is not currently exposed.
43    /// You can just use [`ToString`] instead.
44    // FIXME turn this into an enum sorta thing?
45    pub fn get_parameter_bool(&self, index: c_int) -> Result<bool> {
46        let mut value = FMOD_BOOL::FALSE;
47        unsafe {
48            FMOD_DSP_GetParameterBool(self.inner, index, &mut value, std::ptr::null_mut(), 0)
49                .to_result()?;
50        }
51        Ok(value.into())
52    }
53
54    /// Sets a binary data parameter by index.
55    ///
56    /// Certain data types are predefined by the system and can be specified via the FMOD_DSP_PARAMETER_DESC_DATA, see [`DspParameterDataType`]
57    ///
58    /// # Safety
59    ///
60    /// You must ensure that the data type passed in via `data` matches the data type expected by the [`Dsp`] unit.
61    // FIXME: does FMOD copy the data?
62    // FIXME: fmod has various predefined data types, should we expose them?
63    pub unsafe fn set_parameter_data(&self, index: c_int, data: &[u8]) -> Result<()> {
64        unsafe {
65            FMOD_DSP_SetParameterData(
66                self.inner,
67                index,
68                data.as_ptr() as *mut _,
69                data.len() as c_uint,
70            )
71            .to_result()
72        }
73    }
74
75    /// Retrieves a binary data parameter by index.
76    ///
77    /// Note: FMOD also returns a string representation of the parameter value, but this is not currently exposed.
78    // FIXME is this safe???
79    pub fn get_parameter_data(&self, index: c_int) -> Result<Vec<u8>> {
80        let mut value = std::ptr::null_mut();
81        let mut length = 0;
82        unsafe {
83            FMOD_DSP_GetParameterData(
84                self.inner,
85                index,
86                &mut value,
87                &mut length,
88                std::ptr::null_mut(),
89                0,
90            )
91            .to_result()?;
92
93            let slice = std::slice::from_raw_parts_mut(value.cast(), length as usize);
94            Ok(slice.to_vec())
95        }
96    }
97
98    /// Sets a floating point parameter by index.
99    pub fn set_parameter_float(&self, index: c_int, value: c_float) -> Result<()> {
100        unsafe { FMOD_DSP_SetParameterFloat(self.inner, index, value).to_result() }
101    }
102
103    /// Retrieves a floating point parameter by index.
104    ///
105    /// Note: FMOD also returns a string representation of the parameter value, but this is not currently exposed.
106    /// You can just use [`ToString`] instead.
107    pub fn get_parameter_float(&self, index: c_int) -> Result<c_float> {
108        let mut value = 0.0;
109        unsafe {
110            FMOD_DSP_GetParameterFloat(self.inner, index, &mut value, std::ptr::null_mut(), 0)
111                .to_result()?;
112        }
113        Ok(value)
114    }
115
116    /// Sets an integer parameter by index.
117    pub fn set_parameter_int(&self, index: c_int, value: c_int) -> Result<()> {
118        unsafe { FMOD_DSP_SetParameterInt(self.inner, index, value).to_result() }
119    }
120
121    /// Retrieves an integer parameter by index.
122    ///
123    /// Note: FMOD also returns a string representation of the parameter value, but this is not currently exposed.
124    /// You can just use [`ToString`] instead.
125    pub fn get_parameter_int(&self, index: c_int) -> Result<c_int> {
126        let mut value = 0;
127        unsafe {
128            FMOD_DSP_GetParameterInt(self.inner, index, &mut value, std::ptr::null_mut(), 0)
129                .to_result()?;
130        }
131        Ok(value)
132    }
133
134    /// Retrieve information about a specified parameter.
135    pub fn get_parameter_info(&self, index: c_int) -> Result<DspParameterDescription> {
136        let mut desc = std::ptr::null_mut();
137        unsafe {
138            FMOD_DSP_GetParameterInfo(self.inner, index, &mut desc).to_result()?;
139            let desc = DspParameterDescription::from_ffi(*desc); // oh god this is *awful*
140            Ok(desc)
141        }
142    }
143}