1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
// Copyright (c) 2024 Melody Madeline Lyons
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use fmod_sys::*;
bitflags::bitflags! {
/// Configuration flags used when initializing the System object.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct InitFlags: FMOD_INITFLAGS {
/// Initialize normally
const NORMAL = FMOD_INIT_NORMAL;
/// No stream thread is created internally.
/// Streams are driven from [`System::update`]. Mainly used with non-realtime outputs.
const STREAM_FROM_UPDATE = FMOD_INIT_STREAM_FROM_UPDATE;
/// No mixer thread is created internally.
/// Mixing is driven from [`System::update`].
/// Only applies to polling based output modes such as [`FMOD_OUTPUTTYPE_NOSOUND`], [`FMOD_OUTPUTTYPE_WAVWRITER`].
const MIX_FROM_UPDATE = FMOD_INIT_MIX_FROM_UPDATE;
/// 3D calculations will be performed in right-handed coordinates, instead of the default of left-handed coordinates.
/// See the Handedness section of the Glossary for more information.
const RIGHTHANDED_3D = FMOD_INIT_3D_RIGHTHANDED;
/// Enables hard clipping of output values greater than 1.0f or less than -1.0f.
const CLIP_OUTPUT = FMOD_INIT_CLIP_OUTPUT;
/// Enables usage of [`ChannelControl::setLowPassGain`],
/// [`ChannelControl::set3DOcclusion`], or automatic usage by the Geometry API.
///
/// All voices will add a software lowpass filter effect into the DSP chain which is idle unless one of the previous
/// functions/features are used.
const CHANNEL_LOWPASS = FMOD_INIT_CHANNEL_LOWPASS;
/// All [`FMOD_3D`] based voices add a software low pass and highpass filter effect into the DSP chain,
/// which acts as a distance-automated bandpass filter.
///
/// Use [`System::setAdvancedSettings`] to adjust the center frequency.
const CHANNEL_DISTANCE_FILTER = FMOD_INIT_CHANNEL_DISTANCEFILTER;
/// Enable TCP/IP based host which allows FMOD Studio or FMOD Profiler to connect to it,
/// and view memory, CPU and the DSP graph in real-time.
const PROFILE_ENABLE = FMOD_INIT_PROFILE_ENABLE;
/// Any sounds that are 0 volume will go virtual and not be processed except for having their positions updated virtually.
///
/// Use [`System::setAdvancedSettings`] to adjust what volume besides zero to switch to virtual at.
const VOL_0_BECOMES_VIRTUAL = FMOD_INIT_VOL0_BECOMES_VIRTUAL;
/// With the geometry engine, only process the closest polygon rather than accumulating all polygons the sound to listener line intersects.
const GEOMETRY_USE_CLOSEST = FMOD_INIT_GEOMETRY_USECLOSEST;
/// When using [`FMOD_SPEAKERMODE_5POINT1`] with a stereo output device,
/// use the Dolby Pro Logic II downmix algorithm instead of the default stereo downmix algorithm.
const PREFER_DOLBY_DOWNMIX = FMOD_INIT_PREFER_DOLBY_DOWNMIX;
/// This flag cannot be used normally as this crate has guardrails preventing it.
/// It is still here for completeness' sake, though.
const THREAD_UNSAFE = FMOD_INIT_THREAD_UNSAFE;
/// Slower, but adds level metering for every single DSP unit in the graph.
/// Use [`DSP::setMeteringEnabled`] to turn meters off individually.
///
/// Setting this flag implies [`PROFILE_ENABLE`].
const PROFILE_METER_ALL = FMOD_INIT_PROFILE_METER_ALL;
/// Enables memory allocation tracking.
/// Currently this is only useful when using the Studio API.
/// Increases memory footprint and reduces performance.
///
/// This flag is implied by [`FMOD_STUDIO_INIT_MEMORY_TRACKING`].
const MEMORY_TRACKING = FMOD_INIT_MEMORY_TRACKING;
}
}
impl From<FMOD_INITFLAGS> for InitFlags {
fn from(value: FMOD_INITFLAGS) -> Self {
InitFlags::from_bits_truncate(value)
}
}
impl From<InitFlags> for FMOD_INITFLAGS {
fn from(value: InitFlags) -> Self {
value.bits()
}
}
bitflags::bitflags! {
/// Bitfield for specifying the CPU core a given thread runs on.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct ThreadAffinity: FMOD_THREAD_AFFINITY {
/// For a given thread use the default listed below, i.e. [`FMOD_THREAD_TYPE_MIXER`] uses [`FMOD_THREAD_AFFINITY_MIXER`].
const GROUP_DEFAULT = FMOD_THREAD_AFFINITY_GROUP_DEFAULT as FMOD_THREAD_AFFINITY;
/// Grouping A is recommended to isolate the mixer thread [`FMOD_THREAD_TYPE_MIXER`].
const GROUP_A = FMOD_THREAD_AFFINITY_GROUP_A as FMOD_THREAD_AFFINITY;
/// Grouping B is recommended to isolate the Studio update thread [`FMOD_THREAD_TYPE_STUDIO_UPDATE`].
const GROUP_B = FMOD_THREAD_AFFINITY_GROUP_B as FMOD_THREAD_AFFINITY;
/// Grouping C is recommended for all remaining threads.
const GROUP_C = FMOD_THREAD_AFFINITY_GROUP_C as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_MIXER`].
const MIXER = FMOD_THREAD_AFFINITY_MIXER as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_FEEDER`].
const FEEDER = FMOD_THREAD_AFFINITY_FEEDER as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_STREAM`].
const STREAM = FMOD_THREAD_AFFINITY_STREAM as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_FILE`].
const FILE = FMOD_THREAD_AFFINITY_FILE as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_NONBLOCKING`].
const NONBLOCKING = FMOD_THREAD_AFFINITY_NONBLOCKING as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_RECORD`].
const RECORD = FMOD_THREAD_AFFINITY_RECORD as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_GEOMETRY`].
const GEOMETRY = FMOD_THREAD_AFFINITY_GEOMETRY as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_PROFILER`].
const PROFILER = FMOD_THREAD_AFFINITY_PROFILER as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_STUDIO_UPDATE`].
const STUDIO_UPDATE = FMOD_THREAD_AFFINITY_STUDIO_UPDATE as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_STUDIO_LOAD_BANK`].
const STUDIO_LOAD_BANK = FMOD_THREAD_AFFINITY_STUDIO_LOAD_BANK as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_STUDIO_LOAD_SAMPLE`].
const STUDIO_LOAD_SAMPLE = FMOD_THREAD_AFFINITY_STUDIO_LOAD_SAMPLE as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_CONVOLUTION1`].
const CONVOLUTION_1 = FMOD_THREAD_AFFINITY_CONVOLUTION1 as FMOD_THREAD_AFFINITY;
/// Default affinity for [`FMOD_THREAD_TYPE_CONVOLUTION2`].
const CONVOLUTION_2 = FMOD_THREAD_AFFINITY_CONVOLUTION2 as FMOD_THREAD_AFFINITY;
/// Assign to all cores.
const CORE_ALL = FMOD_THREAD_AFFINITY_CORE_ALL as FMOD_THREAD_AFFINITY;
/// Assign to core 0.
const CORE_0 = FMOD_THREAD_AFFINITY_CORE_0 as FMOD_THREAD_AFFINITY;
/// Assign to core 1.
const CORE_1 = FMOD_THREAD_AFFINITY_CORE_1 as FMOD_THREAD_AFFINITY;
/// Assign to core 2.
const CORE_2 = FMOD_THREAD_AFFINITY_CORE_2 as FMOD_THREAD_AFFINITY;
/// Assign to core 3.
const CORE_3 = FMOD_THREAD_AFFINITY_CORE_3 as FMOD_THREAD_AFFINITY;
/// Assign to core 4.
const CORE_4 = FMOD_THREAD_AFFINITY_CORE_4 as FMOD_THREAD_AFFINITY;
/// Assign to core 5.
const CORE_5 = FMOD_THREAD_AFFINITY_CORE_5 as FMOD_THREAD_AFFINITY;
/// Assign to core 6.
const CORE_6 = FMOD_THREAD_AFFINITY_CORE_6 as FMOD_THREAD_AFFINITY;
/// Assign to core 7.
const CORE_7 = FMOD_THREAD_AFFINITY_CORE_7 as FMOD_THREAD_AFFINITY;
/// Assign to core 8.
const CORE_8 = FMOD_THREAD_AFFINITY_CORE_8 as FMOD_THREAD_AFFINITY;
/// Assign to core 9.
const CORE_9 = FMOD_THREAD_AFFINITY_CORE_9 as FMOD_THREAD_AFFINITY;
/// Assign to core 10.
const CORE_10 = FMOD_THREAD_AFFINITY_CORE_10 as FMOD_THREAD_AFFINITY;
/// Assign to core 11.
const CORE_11 = FMOD_THREAD_AFFINITY_CORE_11 as FMOD_THREAD_AFFINITY;
/// Assign to core 12.
const CORE_12 = FMOD_THREAD_AFFINITY_CORE_12 as FMOD_THREAD_AFFINITY;
/// Assign to core 13.
const CORE_13 = FMOD_THREAD_AFFINITY_CORE_13 as FMOD_THREAD_AFFINITY;
/// Assign to core 14.
const CORE_14 = FMOD_THREAD_AFFINITY_CORE_14 as FMOD_THREAD_AFFINITY;
/// Assign to core 15.
const CORE_15 = FMOD_THREAD_AFFINITY_CORE_15 as FMOD_THREAD_AFFINITY;
}
}
impl From<FMOD_THREAD_AFFINITY> for ThreadAffinity {
fn from(value: FMOD_THREAD_AFFINITY) -> Self {
ThreadAffinity::from_bits_truncate(value)
}
}
impl From<ThreadAffinity> for FMOD_THREAD_AFFINITY {
fn from(value: ThreadAffinity) -> Self {
value.bits()
}
}
bitflags::bitflags! {
/// [`Sound`] description bitfields.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Mode: FMOD_MODE {
/// Default for all modes listed below.
const DEFAULT = FMOD_DEFAULT;
/// For non looping [`Sound`]s. (Default)
///
/// Overrides [`LOOP_NORMAL`] / [`LOOP_BIDI`].
const LOOP_OFF = FMOD_LOOP_OFF;
/// For forward looping [`Sound`]s.
const LOOP_NORMAL = FMOD_LOOP_NORMAL;
/// For bidirectional looping [`Sound`]s. (only works on non-streaming, real voices).
const LOOP_BIDI = FMOD_LOOP_BIDI;
/// Ignores any 3d processing. (Default)
const D2 = FMOD_2D;
/// Makes the [`Sound`] positionable in 3D. Overrides [`D2`].
const D3 = FMOD_3D;
/// Decompress at runtime,
/// streaming from the source provided (ie from disk).
/// Overrides [`FMOD_CREATESAMPLE`] and [`FMOD_CREATECOMPRESSEDSAMPLE`].
/// Note a stream can only be played once at a time due to a stream only having 1 stream buffer and file handle.
/// Open multiple streams to have them play concurrently.
const CREATE_STREAM = FMOD_CREATESTREAM;
/// Decompress at loadtime,
/// decompressing or decoding whole file into memory as the target sample format (ie PCM).
/// Fastest for playback and most flexible.
const CREATE_SAMPLE = FMOD_CREATESAMPLE;
/// Load MP2/MP3/FADPCM/IMAADPCM/Vorbis/AT9 or XMA into memory and leave it compressed.
/// Vorbis/AT9/FADPCM encoding only supported in the .FSB container format.
/// During playback the FMOD software mixer will decode it in realtime as a 'compressed sample'.
/// Overrides [`FMOD_CREATESAMPLE`].
/// If the sound data is not one of the supported formats,
/// it will behave as if it was created with [`FMOD_CREATESAMPLE`] and decode the sound into PCM.
const CREATE_COMPRESSED_SAMPLE = FMOD_CREATECOMPRESSEDSAMPLE;
/// Opens a user-created static sample or stream.
const OPEN_USER = FMOD_OPENUSER;
/// Opens a sound with a pointer to memory.
/// Duplicates the pointer into its own buffer.
const OPEN_MEMORY = FMOD_OPENMEMORY;
/// Opens a sound with a pointer to memory.
const OPEN_MEMORY_POINT = FMOD_OPENMEMORY_POINT;
/// Will ignore file format and treat as raw pcm.
const OPEN_RAW = FMOD_OPENRAW;
/// Just open the file, don't prebuffer or read.
/// Good for fast opens for info, or when [`Sound::readData`] is to be used.
const OPEN_ONLY = FMOD_OPENONLY;
/// For [`System::create_sound`] - for accurate [`Sound::get_length`] / [`Channel::set_position`] on VBR MP3,
/// and MOD/S3M/XM/IT/MIDI files.
/// Scans file first, so takes longer to open.
/// [`FMOD_OPENONLY`] does not affect this.
const ACCURATE_TIME = FMOD_ACCURATETIME;
/// For corrupted / bad MP3 files.
/// This will search all the way through the file until it hits a valid MPEG header.
/// Normally only searches for 4k.
const MPEG_SEARCH = FMOD_MPEGSEARCH;
/// For opening [`Sound`]s and getting streamed subsounds (seeking) asynchronously.
/// Use [`Sound::get_open_state`] to poll the state of the [`Sound`] as it opens or retrieves the subsound in the background.
const NONBLOCKING = FMOD_NONBLOCKING;
/// Unique [`Sound`], can only be played one at a time.
const UNIQUE = FMOD_UNIQUE;
/// Make the [`Sound`]'s position, velocity and orientation relative to the listener.
const HEADRELATIVE_3D = FMOD_3D_HEADRELATIVE;
/// Make the [`Sound`]'s position, velocity and orientation absolute (relative to the world). (Default)
const WORLDRELATIVE_3D = FMOD_3D_WORLDRELATIVE;
/// This sound follows an inverse roll-off model.
/// Below mindistance, the volume is unattenuated; as distance increases above mindistance,
/// the volume attenuates using mindistance/distance as the gradient until it reaches maxdistance,
/// where it stops attenuating.
/// For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale.
/// This roll-off mode accurately models the way sounds attenuate over distance in the real world. (Default)
const INVERSE_ROLLOFF_3D = FMOD_3D_INVERSEROLLOFF;
/// This sound follows a linear roll-off model.
/// Below mindistance, the volume is unattenuated; as distance increases from mindistance to maxdistance,
/// the volume attenuates to silence using a linear gradient.
/// For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale.
/// While this roll-off mode is not as realistic as inverse roll-off mode, it is easier to comprehend.
const LINEAR_ROLLOFF_3D = FMOD_3D_LINEARROLLOFF;
/// This sound follows a linear-square roll-off model.
/// Below mindistance, the volume is unattenuated; as distance increases from mindistance to maxdistance,
/// the volume attenuates to silence according to a linear squared gradient.
/// For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale.
/// This roll-off mode provides steeper volume ramping close to the mindistance,
/// and more gradual ramping close to the maxdistance, than linear roll-off mode.
const LINEAR_SQUARE_ROLLOFF_3D = FMOD_3D_LINEARSQUAREROLLOFF;
/// This sound follows a combination of the inverse and linear-square roll-off models.
/// At short distances where inverse roll-off would provide greater attenuation,
/// it functions as inverse roll-off mode; then at greater distances where linear-square roll-off mode would provide greater attenuation,
/// it uses that roll-off mode instead.
/// For this roll-off mode, distance values greater than mindistance are scaled according to the rolloffscale.
/// Inverse tapered roll-off mode approximates realistic behavior while still guaranteeing the sound attenuates to silence at maxdistance.
const INVERSE_TAPERED_ROLLOFF_3D = FMOD_3D_INVERSETAPEREDROLLOFF;
/// This sound follow a roll-off model defined by [`Sound::set3DCustomRolloff`] / [`ChannelControl::set3DCustomRolloff`].
/// This roll-off mode provides greater freedom and flexibility than any other, but must be defined manually.
const CUSTOM_ROLLOFF_3D = FMOD_3D_CUSTOMROLLOFF;
/// Is not affected by geometry occlusion.
/// If not specified in [`Sound::setMode`], or [`ChannelControl::setMode`],
/// the flag is cleared and it is affected by geometry again.
const IGNORE_GEOMETRY_3D = FMOD_3D_IGNOREGEOMETRY;
/// Skips id3v2/asf/etc tag checks when opening a Sound, to reduce seek/read overhead when opening files.
const IGNORE_TAGS = FMOD_IGNORETAGS;
/// Removes some features from samples to give a lower memory overhead, like [`Sound::getName`].
const LOWMEM = FMOD_LOWMEM;
/// For Channels that start virtual (due to being quiet or low importance),
/// instead of swapping back to audible,
/// and playing at the correct offset according to time, this flag makes the Channel play from the start.
const VIRTUAL_PLAYFROM_START = FMOD_VIRTUAL_PLAYFROMSTART;
}
}
impl From<FMOD_MODE> for Mode {
fn from(value: FMOD_MODE) -> Self {
Mode::from_bits_truncate(value)
}
}
impl From<Mode> for FMOD_MODE {
fn from(value: Mode) -> Self {
value.bits()
}
}
bitflags::bitflags! {
/// Flags that describe the speakers present in a given signal.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct ChannelMask: FMOD_CHANNELMASK {
/// Front left channel.
const FRONT_LEFT = FMOD_CHANNELMASK_FRONT_LEFT;
/// Front right channel.
const FRONT_RIGHT = FMOD_CHANNELMASK_FRONT_RIGHT;
/// Front center channel.
const FRONT_CENTER = FMOD_CHANNELMASK_FRONT_CENTER;
/// Low frequency channel.
const LOW_FREQUENCY = FMOD_CHANNELMASK_LOW_FREQUENCY;
/// Surround left channel.
const SURROUND_LEFT = FMOD_CHANNELMASK_SURROUND_LEFT;
/// Surround right channel.
const SURROUND_RIGHT = FMOD_CHANNELMASK_SURROUND_RIGHT;
/// Back left channel.
const BACK_LEFT = FMOD_CHANNELMASK_BACK_LEFT;
/// Back right channel.
const BACK_RIGHT = FMOD_CHANNELMASK_BACK_RIGHT;
/// Back center channel, not represented in any [`FMOD_SPEAKERMODE`].
const BACK_CENTER = FMOD_CHANNELMASK_BACK_CENTER;
/// Mono channel mask.
const MONO = FMOD_CHANNELMASK_MONO;
/// Stereo channel mask.
const STEREO = FMOD_CHANNELMASK_STEREO;
/// Left / right / center channel mask.
const LRC = FMOD_CHANNELMASK_LRC;
/// Quadphonic channel mask.
const QUAD = FMOD_CHANNELMASK_QUAD;
/// 5.0 surround sound channel mask.
const SURROUND = FMOD_CHANNELMASK_SURROUND;
/// 5.1 surround sound channel mask.
const _5POINT1 = FMOD_CHANNELMASK_5POINT1;
/// 5.1 surround sound channel mask, using rears instead of surrounds.
const _5POINT1_REARS = FMOD_CHANNELMASK_5POINT1_REARS;
/// 7.0 surround sound channel mask.
const _7POINT0 = FMOD_CHANNELMASK_7POINT0;
/// 7.1 surround sound channel mask.
const _7POINT1 = FMOD_CHANNELMASK_7POINT1;
}
}
impl From<FMOD_CHANNELMASK> for ChannelMask {
fn from(value: FMOD_CHANNELMASK) -> Self {
ChannelMask::from_bits_truncate(value)
}
}
impl From<ChannelMask> for FMOD_CHANNELMASK {
fn from(value: ChannelMask) -> Self {
value.bits()
}
}
bitflags::bitflags! {
/// Flags that provide additional information about a particular driver.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct DriverState: FMOD_DRIVER_STATE {
/// Device is currently plugged in.
const CONNECTED = FMOD_DRIVER_STATE_CONNECTED;
/// Device is the users preferred choice.
const DEFAULT = FMOD_DRIVER_STATE_DEFAULT;
}
}
impl From<FMOD_DRIVER_STATE> for DriverState {
fn from(value: FMOD_DRIVER_STATE) -> Self {
DriverState::from_bits_truncate(value)
}
}
impl From<DriverState> for FMOD_DRIVER_STATE {
fn from(value: DriverState) -> Self {
value.bits()
}
}