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}