1use fmod_sys::*;
8use lanyard::{Utf8CStr, Utf8CString};
9use num_enum::UnsafeFromPrimitive;
10use std::ffi::{c_float, c_int, c_uint};
11
12use super::{InstanceType, ParameterFlags, ParameterKind, UserPropertyKind};
13use crate::{
14 core::{Dsp, Sound},
15 Guid, SoundBuilder,
16};
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct MemoryUsage {
20 pub exclusive: c_int,
21 pub inclusive: c_int,
22 pub sample_data: c_int,
23}
24
25impl From<FMOD_STUDIO_MEMORY_USAGE> for MemoryUsage {
26 fn from(value: FMOD_STUDIO_MEMORY_USAGE) -> Self {
27 MemoryUsage {
28 exclusive: value.exclusive,
29 inclusive: value.inclusive,
30 sample_data: value.sampledata,
31 }
32 }
33}
34
35impl From<MemoryUsage> for FMOD_STUDIO_MEMORY_USAGE {
36 fn from(value: MemoryUsage) -> Self {
37 FMOD_STUDIO_MEMORY_USAGE {
38 exclusive: value.exclusive,
39 inclusive: value.inclusive,
40 sampledata: value.sample_data,
41 }
42 }
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46#[repr(C)]
48pub struct ParameterID {
49 pub data_1: c_uint,
50 pub data_2: c_uint,
51}
52
53impl From<FMOD_STUDIO_PARAMETER_ID> for ParameterID {
54 fn from(value: FMOD_STUDIO_PARAMETER_ID) -> Self {
55 ParameterID {
56 data_1: value.data1,
57 data_2: value.data2,
58 }
59 }
60}
61
62impl From<ParameterID> for FMOD_STUDIO_PARAMETER_ID {
63 fn from(value: ParameterID) -> Self {
64 FMOD_STUDIO_PARAMETER_ID {
65 data1: value.data_1,
66 data2: value.data_2,
67 }
68 }
69}
70
71#[derive(Clone, Default, PartialEq, Eq, Debug)]
73pub struct AdvancedSettings {
74 pub command_queue_size: c_uint,
75 pub handle_initial_size: c_uint,
76 pub studioupdateperiod: c_int,
77 pub idle_sample_data_pool_size: c_int,
78 pub streaming_schedule_delay: c_uint,
79 pub encryption_key: Option<Utf8CString>, }
81
82impl AdvancedSettings {
83 pub unsafe fn from_ffi(value: FMOD_STUDIO_ADVANCEDSETTINGS) -> Self {
91 let encryption_key = if value.encryptionkey.is_null() {
92 None
93 } else {
94 let cstring = unsafe { Utf8CStr::from_ptr_unchecked(value.encryptionkey) }.to_cstring();
95 Some(cstring)
96 };
97
98 Self {
99 command_queue_size: value.commandqueuesize,
100 handle_initial_size: value.handleinitialsize,
101 studioupdateperiod: value.studioupdateperiod,
102 idle_sample_data_pool_size: value.idlesampledatapoolsize,
103 streaming_schedule_delay: value.streamingscheduledelay,
104 encryption_key,
105 }
106 }
107}
108
109impl From<&AdvancedSettings> for FMOD_STUDIO_ADVANCEDSETTINGS {
111 fn from(value: &AdvancedSettings) -> Self {
112 let encryption_key = value
113 .encryption_key
114 .as_deref()
115 .map_or(std::ptr::null(), Utf8CStr::as_ptr);
116
117 FMOD_STUDIO_ADVANCEDSETTINGS {
118 cbsize: std::mem::size_of::<Self>() as c_int,
119 commandqueuesize: value.command_queue_size,
120 handleinitialsize: value.handle_initial_size,
121 studioupdateperiod: value.studioupdateperiod,
122 idlesampledatapoolsize: value.idle_sample_data_pool_size,
123 streamingscheduledelay: value.streaming_schedule_delay,
124 encryptionkey: encryption_key,
125 }
126 }
127}
128
129#[derive(Clone, PartialEq, Debug)]
130pub struct ParameterDescription {
131 pub name: Utf8CString,
132 pub id: ParameterID,
133 pub minimum: c_float,
134 pub maximum: c_float,
135 pub default_value: c_float,
136 pub kind: ParameterKind,
137 pub flags: ParameterFlags,
138 pub guid: Guid,
139}
140
141impl From<&ParameterDescription> for FMOD_STUDIO_PARAMETER_DESCRIPTION {
143 fn from(value: &ParameterDescription) -> Self {
144 FMOD_STUDIO_PARAMETER_DESCRIPTION {
145 name: value.name.as_ptr(),
146 id: value.id.into(),
147 minimum: value.minimum,
148 maximum: value.maximum,
149 defaultvalue: value.default_value,
150 type_: value.kind.into(),
151 flags: value.flags.into(),
152 guid: value.guid.into(),
153 }
154 }
155}
156
157impl ParameterDescription {
158 pub unsafe fn from_ffi(value: FMOD_STUDIO_PARAMETER_DESCRIPTION) -> ParameterDescription {
166 unsafe {
167 ParameterDescription {
168 name: Utf8CStr::from_ptr_unchecked(value.name).to_cstring(),
169 id: value.id.into(),
170 minimum: value.minimum,
171 maximum: value.maximum,
172 default_value: value.defaultvalue,
173 kind: ParameterKind::unchecked_transmute_from(value.type_),
174 flags: value.flags.into(),
175 guid: value.guid.into(),
176 }
177 }
178 }
179}
180
181#[derive(Clone, PartialEq, Debug)]
182pub struct UserProperty {
183 pub name: Utf8CString,
184 pub kind: UserPropertyKind,
185}
186
187impl UserProperty {
188 pub unsafe fn from_ffi(value: FMOD_STUDIO_USER_PROPERTY) -> Self {
197 unsafe {
198 UserProperty {
199 name: Utf8CStr::from_ptr_unchecked(value.name).to_cstring(),
200 kind: match value.type_ {
201 FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER => {
202 UserPropertyKind::Int(value.__bindgen_anon_1.intvalue)
203 }
204 FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN => {
205 UserPropertyKind::Bool(value.__bindgen_anon_1.boolvalue.into())
206 }
207 FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT => {
208 UserPropertyKind::Float(value.__bindgen_anon_1.floatvalue)
209 }
210 FMOD_STUDIO_USER_PROPERTY_TYPE_STRING => {
211 let cstring =
212 Utf8CStr::from_ptr_unchecked(value.__bindgen_anon_1.stringvalue)
213 .to_cstring();
214 UserPropertyKind::String(cstring)
215 }
216 v => panic!("invalid user property type {v}"),
217 },
218 }
219 }
220 }
221}
222
223impl From<&UserProperty> for FMOD_STUDIO_USER_PROPERTY {
224 fn from(value: &UserProperty) -> Self {
225 let (kind, union) = match value.kind {
226 UserPropertyKind::Int(v) => (
227 FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER,
228 FMOD_STUDIO_USER_PROPERTY__bindgen_ty_1 { intvalue: v },
229 ),
230 UserPropertyKind::Bool(v) => (
231 FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN,
232 FMOD_STUDIO_USER_PROPERTY__bindgen_ty_1 {
233 boolvalue: v.into(),
234 },
235 ),
236 UserPropertyKind::Float(v) => (
237 FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT,
238 FMOD_STUDIO_USER_PROPERTY__bindgen_ty_1 { floatvalue: v },
239 ),
240 UserPropertyKind::String(ref v) => (
241 FMOD_STUDIO_USER_PROPERTY_TYPE_STRING,
242 FMOD_STUDIO_USER_PROPERTY__bindgen_ty_1 {
243 stringvalue: v.as_ptr(),
244 },
245 ),
246 };
247 FMOD_STUDIO_USER_PROPERTY {
248 name: value.name.as_ptr(),
249 type_: kind,
250 __bindgen_anon_1: union,
251 }
252 }
253}
254
255#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
256pub struct BufferInfo {
257 pub current_usage: c_int,
258 pub peak_usage: c_int,
259 pub capacity: c_int,
260 pub stall_count: c_int,
261 pub stall_time: c_float,
262}
263
264impl From<FMOD_STUDIO_BUFFER_INFO> for BufferInfo {
265 fn from(value: FMOD_STUDIO_BUFFER_INFO) -> Self {
266 BufferInfo {
267 current_usage: value.currentusage,
268 peak_usage: value.peakusage,
269 capacity: value.capacity,
270 stall_count: value.stallcount,
271 stall_time: value.stalltime,
272 }
273 }
274}
275
276impl From<BufferInfo> for FMOD_STUDIO_BUFFER_INFO {
277 fn from(value: BufferInfo) -> Self {
278 FMOD_STUDIO_BUFFER_INFO {
279 currentusage: value.current_usage,
280 peakusage: value.peak_usage,
281 capacity: value.capacity,
282 stallcount: value.stall_count,
283 stalltime: value.stall_time,
284 }
285 }
286}
287
288#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
289pub struct BufferUsage {
290 pub studio_command_queue: BufferInfo,
291 pub studio_handle: BufferInfo,
292}
293
294impl From<FMOD_STUDIO_BUFFER_USAGE> for BufferUsage {
295 fn from(value: FMOD_STUDIO_BUFFER_USAGE) -> Self {
296 BufferUsage {
297 studio_command_queue: value.studiocommandqueue.into(),
298 studio_handle: value.studiohandle.into(),
299 }
300 }
301}
302
303impl From<BufferUsage> for FMOD_STUDIO_BUFFER_USAGE {
304 fn from(value: BufferUsage) -> Self {
305 FMOD_STUDIO_BUFFER_USAGE {
306 studiocommandqueue: value.studio_command_queue.into(),
307 studiohandle: value.studio_handle.into(),
308 }
309 }
310}
311
312#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
313pub struct CpuUsage {
314 pub update: c_float,
315}
316
317impl From<FMOD_STUDIO_CPU_USAGE> for CpuUsage {
318 fn from(value: FMOD_STUDIO_CPU_USAGE) -> Self {
319 CpuUsage {
320 update: value.update,
321 }
322 }
323}
324
325impl From<CpuUsage> for FMOD_STUDIO_CPU_USAGE {
326 fn from(value: CpuUsage) -> Self {
327 FMOD_STUDIO_CPU_USAGE {
328 update: value.update,
329 }
330 }
331}
332
333#[derive(Debug)]
334pub struct SoundInfo<'a> {
335 pub builder: SoundBuilder<'a>,
336 pub subsound_index: c_int,
337}
338
339impl<'a> SoundInfo<'a> {
340 pub unsafe fn from_ffi(value: FMOD_STUDIO_SOUND_INFO) -> Self {
346 SoundInfo {
347 builder: unsafe {
348 SoundBuilder::from_ffi(value.name_or_data, value.mode, value.exinfo)
349 },
350 subsound_index: value.subsoundindex,
351 }
352 }
353}
354
355impl From<&SoundInfo<'_>> for FMOD_STUDIO_SOUND_INFO {
356 fn from(value: &SoundInfo<'_>) -> Self {
357 FMOD_STUDIO_SOUND_INFO {
358 name_or_data: value.builder.name_or_data,
359 mode: value.builder.mode,
360 exinfo: value.builder.create_sound_ex_info,
361 subsoundindex: value.subsound_index,
362 }
363 }
364}
365
366#[derive(Debug, Clone)]
367pub struct CommandInfo {
368 pub command_name: Utf8CString,
369 pub parent_command_index: c_int,
370 pub frame_number: c_int,
371 pub frame_time: c_float,
372 pub instance_type: InstanceType,
373 pub output_type: InstanceType,
374 pub instance_handle: c_uint,
375 pub output_handle: c_uint,
376}
377
378impl From<&CommandInfo> for FMOD_STUDIO_COMMAND_INFO {
379 fn from(value: &CommandInfo) -> Self {
380 FMOD_STUDIO_COMMAND_INFO {
381 commandname: value.command_name.as_ptr(),
382 parentcommandindex: value.parent_command_index,
383 framenumber: value.frame_number,
384 frametime: value.frame_time,
385 instancetype: value.instance_type.into(),
386 outputtype: value.output_type.into(),
387 instancehandle: value.instance_handle,
388 outputhandle: value.output_handle,
389 }
390 }
391}
392
393impl CommandInfo {
394 pub unsafe fn from_ffi(value: FMOD_STUDIO_COMMAND_INFO) -> Self {
402 CommandInfo {
403 command_name: unsafe { Utf8CStr::from_ptr_unchecked(value.commandname).to_cstring() },
404 parent_command_index: value.parentcommandindex,
405 frame_number: value.framenumber,
406 frame_time: value.frametime,
407 instance_type: unsafe { InstanceType::unchecked_transmute_from(value.instancetype) },
408 output_type: unsafe { InstanceType::unchecked_transmute_from(value.instancetype) },
409 instance_handle: value.instancehandle,
410 output_handle: value.outputhandle,
411 }
412 }
413}
414
415pub struct ProgrammerSoundProperties<'prop> {
416 pub name: Utf8CString,
417 pub sound: &'prop mut Sound,
419 pub subsound_index: &'prop mut c_int,
420}
421
422pub struct PluginInstanceProperties {
423 pub name: Utf8CString,
424 pub dsp: Dsp,
425}
426
427impl From<&PluginInstanceProperties> for FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES {
428 fn from(value: &PluginInstanceProperties) -> Self {
429 FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES {
430 name: value.name.as_ptr(),
431 dsp: value.dsp.inner,
432 }
433 }
434}
435
436impl PluginInstanceProperties {
437 pub unsafe fn from_ffi(value: FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES) -> Self {
445 PluginInstanceProperties {
446 name: unsafe { Utf8CStr::from_ptr_unchecked(value.name) }.to_cstring(),
447 dsp: value.dsp.into(),
448 }
449 }
450}
451
452pub struct TimelineMarkerProperties {
453 pub name: Utf8CString,
454 pub position: c_int,
455}
456
457impl From<&TimelineMarkerProperties> for FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES {
458 fn from(value: &TimelineMarkerProperties) -> Self {
459 FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES {
460 name: value.name.as_ptr(),
461 position: value.position,
462 }
463 }
464}
465
466impl TimelineMarkerProperties {
467 pub unsafe fn from_ffi(value: FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES) -> Self {
475 TimelineMarkerProperties {
476 name: unsafe { Utf8CStr::from_ptr_unchecked(value.name) }.to_cstring(),
477 position: value.position,
478 }
479 }
480}
481
482pub struct TimelineBeatProperties {
483 pub bar: c_int,
484 pub beat: c_int,
485 pub position: c_int,
486 pub tempo: c_float,
487 pub time_signature_upper: c_int,
488 pub time_signature_lower: c_int,
489}
490
491impl From<TimelineBeatProperties> for FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES {
492 fn from(value: TimelineBeatProperties) -> Self {
493 FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES {
494 bar: value.bar,
495 beat: value.beat,
496 position: value.position,
497 tempo: value.tempo,
498 timesignatureupper: value.time_signature_upper,
499 timesignaturelower: value.time_signature_lower,
500 }
501 }
502}
503
504impl From<FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES> for TimelineBeatProperties {
505 fn from(value: FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES) -> Self {
506 TimelineBeatProperties {
507 bar: value.bar,
508 beat: value.beat,
509 position: value.position,
510 tempo: value.tempo,
511 time_signature_upper: value.timesignatureupper,
512 time_signature_lower: value.timesignaturelower,
513 }
514 }
515}
516
517pub struct TimelineNestedBeatProperties {
518 pub event_guid: Guid,
519 pub properties: TimelineBeatProperties,
520}
521
522impl From<TimelineNestedBeatProperties> for FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES {
523 fn from(value: TimelineNestedBeatProperties) -> Self {
524 FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES {
525 eventid: value.event_guid.into(),
526 properties: value.properties.into(),
527 }
528 }
529}
530
531impl From<FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES> for TimelineNestedBeatProperties {
532 fn from(value: FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES) -> Self {
533 TimelineNestedBeatProperties {
534 event_guid: value.eventid.into(),
535 properties: value.properties.into(),
536 }
537 }
538}