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 Guid, SoundBuilder,
15 core::{Dsp, Sound},
16};
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub struct MemoryUsage {
24 pub exclusive: c_int,
26 pub inclusive: c_int,
28 pub sample_data: c_int,
31}
32
33impl From<FMOD_STUDIO_MEMORY_USAGE> for MemoryUsage {
34 fn from(value: FMOD_STUDIO_MEMORY_USAGE) -> Self {
35 MemoryUsage {
36 exclusive: value.exclusive,
37 inclusive: value.inclusive,
38 sample_data: value.sampledata,
39 }
40 }
41}
42
43impl From<MemoryUsage> for FMOD_STUDIO_MEMORY_USAGE {
44 fn from(value: MemoryUsage) -> Self {
45 FMOD_STUDIO_MEMORY_USAGE {
46 exclusive: value.exclusive,
47 inclusive: value.inclusive,
48 sampledata: value.sample_data,
49 }
50 }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57#[repr(C)]
59pub struct ParameterID {
60 pub data_1: c_uint,
62 pub data_2: c_uint,
64}
65
66impl From<FMOD_STUDIO_PARAMETER_ID> for ParameterID {
67 fn from(value: FMOD_STUDIO_PARAMETER_ID) -> Self {
68 ParameterID {
69 data_1: value.data1,
70 data_2: value.data2,
71 }
72 }
73}
74
75impl From<ParameterID> for FMOD_STUDIO_PARAMETER_ID {
76 fn from(value: ParameterID) -> Self {
77 FMOD_STUDIO_PARAMETER_ID {
78 data1: value.data_1,
79 data2: value.data_2,
80 }
81 }
82}
83
84#[derive(Clone, Default, PartialEq, Eq, Debug)]
87pub struct AdvancedSettings {
88 pub command_queue_size: c_uint,
90 pub handle_initial_size: c_uint,
92 pub studio_update_period: c_int,
94 pub idle_sample_data_pool_size: c_int,
96 pub streaming_schedule_delay: c_uint,
99 pub encryption_key: Option<Utf8CString>, }
102
103impl AdvancedSettings {
104 pub unsafe fn from_ffi(value: FMOD_STUDIO_ADVANCEDSETTINGS) -> Self {
112 let encryption_key = if value.encryptionkey.is_null() {
113 None
114 } else {
115 let cstring = unsafe { Utf8CStr::from_ptr_unchecked(value.encryptionkey) }.to_cstring();
116 Some(cstring)
117 };
118
119 Self {
120 command_queue_size: value.commandqueuesize,
121 handle_initial_size: value.handleinitialsize,
122 studio_update_period: value.studioupdateperiod,
123 idle_sample_data_pool_size: value.idlesampledatapoolsize,
124 streaming_schedule_delay: value.streamingscheduledelay,
125 encryption_key,
126 }
127 }
128}
129
130impl From<&AdvancedSettings> for FMOD_STUDIO_ADVANCEDSETTINGS {
132 fn from(value: &AdvancedSettings) -> Self {
133 let encryption_key = value
134 .encryption_key
135 .as_deref()
136 .map_or(std::ptr::null(), Utf8CStr::as_ptr);
137
138 FMOD_STUDIO_ADVANCEDSETTINGS {
139 cbsize: std::mem::size_of::<Self>() as c_int,
140 commandqueuesize: value.command_queue_size,
141 handleinitialsize: value.handle_initial_size,
142 studioupdateperiod: value.studio_update_period,
143 idlesampledatapoolsize: value.idle_sample_data_pool_size,
144 streamingscheduledelay: value.streaming_schedule_delay,
145 encryptionkey: encryption_key,
146 }
147 }
148}
149
150#[derive(Clone, PartialEq, Debug)]
152pub struct ParameterDescription {
153 pub name: Utf8CString,
155 pub id: ParameterID,
157 pub minimum: c_float,
159 pub maximum: c_float,
161 pub default_value: c_float,
163 pub kind: ParameterKind,
165 pub flags: ParameterFlags,
167 pub guid: Guid,
169}
170
171impl From<&ParameterDescription> for FMOD_STUDIO_PARAMETER_DESCRIPTION {
173 fn from(value: &ParameterDescription) -> Self {
174 FMOD_STUDIO_PARAMETER_DESCRIPTION {
175 name: value.name.as_ptr(),
176 id: value.id.into(),
177 minimum: value.minimum,
178 maximum: value.maximum,
179 defaultvalue: value.default_value,
180 type_: value.kind.into(),
181 flags: value.flags.into(),
182 guid: value.guid.into(),
183 }
184 }
185}
186
187impl ParameterDescription {
188 pub unsafe fn from_ffi(value: FMOD_STUDIO_PARAMETER_DESCRIPTION) -> ParameterDescription {
196 unsafe {
197 ParameterDescription {
198 name: Utf8CStr::from_ptr_unchecked(value.name).to_cstring(),
199 id: value.id.into(),
200 minimum: value.minimum,
201 maximum: value.maximum,
202 default_value: value.defaultvalue,
203 kind: ParameterKind::unchecked_transmute_from(value.type_),
204 flags: value.flags.into(),
205 guid: value.guid.into(),
206 }
207 }
208 }
209}
210
211#[derive(Clone, PartialEq, Debug)]
213pub struct UserProperty {
214 pub name: Utf8CString,
216 pub kind: UserPropertyKind,
218}
219
220impl UserProperty {
221 pub unsafe fn from_ffi(value: FMOD_STUDIO_USER_PROPERTY) -> Self {
234 unsafe {
235 UserProperty {
236 name: Utf8CStr::from_ptr_unchecked(value.name).to_cstring(),
237 kind: match value.type_ {
238 FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER => {
239 UserPropertyKind::Int(value.__bindgen_anon_1.intvalue)
240 }
241 FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN => {
242 UserPropertyKind::Bool(value.__bindgen_anon_1.boolvalue.into())
243 }
244 FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT => {
245 UserPropertyKind::Float(value.__bindgen_anon_1.floatvalue)
246 }
247 FMOD_STUDIO_USER_PROPERTY_TYPE_STRING => {
248 let cstring =
249 Utf8CStr::from_ptr_unchecked(value.__bindgen_anon_1.stringvalue)
250 .to_cstring();
251 UserPropertyKind::String(cstring)
252 }
253 v => panic!("invalid user property type {v}"),
254 },
255 }
256 }
257 }
258}
259
260impl From<&UserProperty> for FMOD_STUDIO_USER_PROPERTY {
261 fn from(value: &UserProperty) -> Self {
262 let (kind, union) = match value.kind {
263 UserPropertyKind::Int(v) => (
264 FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER,
265 FMOD_STUDIO_USER_PROPERTY__bindgen_ty_1 { intvalue: v },
266 ),
267 UserPropertyKind::Bool(v) => (
268 FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN,
269 FMOD_STUDIO_USER_PROPERTY__bindgen_ty_1 {
270 boolvalue: v.into(),
271 },
272 ),
273 UserPropertyKind::Float(v) => (
274 FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT,
275 FMOD_STUDIO_USER_PROPERTY__bindgen_ty_1 { floatvalue: v },
276 ),
277 UserPropertyKind::String(ref v) => (
278 FMOD_STUDIO_USER_PROPERTY_TYPE_STRING,
279 FMOD_STUDIO_USER_PROPERTY__bindgen_ty_1 {
280 stringvalue: v.as_ptr(),
281 },
282 ),
283 };
284 FMOD_STUDIO_USER_PROPERTY {
285 name: value.name.as_ptr(),
286 type_: kind,
287 __bindgen_anon_1: union,
288 }
289 }
290}
291
292#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
294pub struct BufferInfo {
295 pub current_usage: c_int,
297 pub peak_usage: c_int,
299 pub capacity: c_int,
301 pub stall_count: c_int,
303 pub stall_time: c_float,
305}
306
307impl From<FMOD_STUDIO_BUFFER_INFO> for BufferInfo {
308 fn from(value: FMOD_STUDIO_BUFFER_INFO) -> Self {
309 BufferInfo {
310 current_usage: value.currentusage,
311 peak_usage: value.peakusage,
312 capacity: value.capacity,
313 stall_count: value.stallcount,
314 stall_time: value.stalltime,
315 }
316 }
317}
318
319impl From<BufferInfo> for FMOD_STUDIO_BUFFER_INFO {
320 fn from(value: BufferInfo) -> Self {
321 FMOD_STUDIO_BUFFER_INFO {
322 currentusage: value.current_usage,
323 peakusage: value.peak_usage,
324 capacity: value.capacity,
325 stallcount: value.stall_count,
326 stalltime: value.stall_time,
327 }
328 }
329}
330
331#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
333pub struct BufferUsage {
334 pub studio_command_queue: BufferInfo,
336 pub studio_handle: BufferInfo,
338}
339
340impl From<FMOD_STUDIO_BUFFER_USAGE> for BufferUsage {
341 fn from(value: FMOD_STUDIO_BUFFER_USAGE) -> Self {
342 BufferUsage {
343 studio_command_queue: value.studiocommandqueue.into(),
344 studio_handle: value.studiohandle.into(),
345 }
346 }
347}
348
349impl From<BufferUsage> for FMOD_STUDIO_BUFFER_USAGE {
350 fn from(value: BufferUsage) -> Self {
351 FMOD_STUDIO_BUFFER_USAGE {
352 studiocommandqueue: value.studio_command_queue.into(),
353 studiohandle: value.studio_handle.into(),
354 }
355 }
356}
357
358#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
360pub struct CpuUsage {
361 pub update: c_float,
364}
365
366impl From<FMOD_STUDIO_CPU_USAGE> for CpuUsage {
367 fn from(value: FMOD_STUDIO_CPU_USAGE) -> Self {
368 CpuUsage {
369 update: value.update,
370 }
371 }
372}
373
374impl From<CpuUsage> for FMOD_STUDIO_CPU_USAGE {
375 fn from(value: CpuUsage) -> Self {
376 FMOD_STUDIO_CPU_USAGE {
377 update: value.update,
378 }
379 }
380}
381
382#[derive(Debug)]
384pub struct SoundInfo<'a> {
385 pub builder: SoundBuilder<'a>,
387 pub subsound_index: c_int,
389}
390
391impl SoundInfo<'_> {
392 pub unsafe fn from_ffi(value: FMOD_STUDIO_SOUND_INFO) -> Self {
398 SoundInfo {
399 builder: unsafe {
400 SoundBuilder::from_ffi(value.name_or_data, value.mode, value.exinfo)
401 },
402 subsound_index: value.subsoundindex,
403 }
404 }
405}
406
407impl From<&SoundInfo<'_>> for FMOD_STUDIO_SOUND_INFO {
408 fn from(value: &SoundInfo<'_>) -> Self {
409 FMOD_STUDIO_SOUND_INFO {
410 name_or_data: value.builder.name_or_data,
411 mode: value.builder.mode,
412 exinfo: value.builder.create_sound_ex_info,
413 subsoundindex: value.subsound_index,
414 }
415 }
416}
417
418#[derive(Debug, Clone)]
420pub struct CommandInfo {
421 pub command_name: Utf8CString,
423 pub parent_command_index: c_int,
425 pub frame_number: c_int,
427 pub frame_time: c_float,
429 pub instance_type: InstanceType,
431 pub output_type: InstanceType,
433 pub instance_handle: c_uint,
435 pub output_handle: c_uint,
437}
438
439impl From<&CommandInfo> for FMOD_STUDIO_COMMAND_INFO {
440 fn from(value: &CommandInfo) -> Self {
441 FMOD_STUDIO_COMMAND_INFO {
442 commandname: value.command_name.as_ptr(),
443 parentcommandindex: value.parent_command_index,
444 framenumber: value.frame_number,
445 frametime: value.frame_time,
446 instancetype: value.instance_type.into(),
447 outputtype: value.output_type.into(),
448 instancehandle: value.instance_handle,
449 outputhandle: value.output_handle,
450 }
451 }
452}
453
454impl CommandInfo {
455 pub unsafe fn from_ffi(value: FMOD_STUDIO_COMMAND_INFO) -> Self {
463 CommandInfo {
464 command_name: unsafe { Utf8CStr::from_ptr_unchecked(value.commandname).to_cstring() },
465 parent_command_index: value.parentcommandindex,
466 frame_number: value.framenumber,
467 frame_time: value.frametime,
468 instance_type: unsafe { InstanceType::unchecked_transmute_from(value.instancetype) },
469 output_type: unsafe { InstanceType::unchecked_transmute_from(value.instancetype) },
470 instance_handle: value.instancehandle,
471 output_handle: value.outputhandle,
472 }
473 }
474}
475
476#[derive(Debug)]
478pub struct ProgrammerSoundProperties<'prop> {
479 pub name: Utf8CString,
481 pub sound: &'prop mut Sound,
484 pub subsound_index: &'prop mut c_int,
486}
487
488#[derive(Debug)]
490pub struct PluginInstanceProperties {
491 pub name: Utf8CString,
493 pub dsp: Dsp,
495}
496
497impl From<&PluginInstanceProperties> for FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES {
498 fn from(value: &PluginInstanceProperties) -> Self {
499 FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES {
500 name: value.name.as_ptr(),
501 dsp: value.dsp.into(),
502 }
503 }
504}
505
506impl PluginInstanceProperties {
507 pub unsafe fn from_ffi(value: FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES) -> Self {
515 PluginInstanceProperties {
516 name: unsafe { Utf8CStr::from_ptr_unchecked(value.name) }.to_cstring(),
517 dsp: unsafe { Dsp::from_ffi(value.dsp) },
518 }
519 }
520}
521
522#[derive(Debug, Clone)]
524pub struct TimelineMarkerProperties {
525 pub name: Utf8CString,
527 pub position: c_int,
529}
530
531impl From<&TimelineMarkerProperties> for FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES {
532 fn from(value: &TimelineMarkerProperties) -> Self {
533 FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES {
534 name: value.name.as_ptr(),
535 position: value.position,
536 }
537 }
538}
539
540impl TimelineMarkerProperties {
541 pub unsafe fn from_ffi(value: FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES) -> Self {
549 TimelineMarkerProperties {
550 name: unsafe { Utf8CStr::from_ptr_unchecked(value.name) }.to_cstring(),
551 position: value.position,
552 }
553 }
554}
555
556#[derive(Clone, Copy, Debug)]
558pub struct TimelineBeatProperties {
559 pub bar: c_int,
561 pub beat: c_int,
563 pub position: c_int,
565 pub tempo: c_float,
567 pub time_signature_upper: c_int,
569 pub time_signature_lower: c_int,
571}
572
573impl From<TimelineBeatProperties> for FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES {
574 fn from(value: TimelineBeatProperties) -> Self {
575 FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES {
576 bar: value.bar,
577 beat: value.beat,
578 position: value.position,
579 tempo: value.tempo,
580 timesignatureupper: value.time_signature_upper,
581 timesignaturelower: value.time_signature_lower,
582 }
583 }
584}
585
586impl From<FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES> for TimelineBeatProperties {
587 fn from(value: FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES) -> Self {
588 TimelineBeatProperties {
589 bar: value.bar,
590 beat: value.beat,
591 position: value.position,
592 tempo: value.tempo,
593 time_signature_upper: value.timesignatureupper,
594 time_signature_lower: value.timesignaturelower,
595 }
596 }
597}
598
599#[derive(Debug, Clone, Copy)]
601pub struct TimelineNestedBeatProperties {
602 pub event_guid: Guid,
604 pub properties: TimelineBeatProperties,
606}
607
608impl From<TimelineNestedBeatProperties> for FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES {
609 fn from(value: TimelineNestedBeatProperties) -> Self {
610 FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES {
611 eventid: value.event_guid.into(),
612 properties: value.properties.into(),
613 }
614 }
615}
616
617impl From<FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES> for TimelineNestedBeatProperties {
618 fn from(value: FMOD_STUDIO_TIMELINE_NESTED_BEAT_PROPERTIES) -> Self {
619 TimelineNestedBeatProperties {
620 event_guid: value.eventid.into(),
621 properties: value.properties.into(),
622 }
623 }
624}