1use std;
4use fmod::{self, ChannelControl};
5
6static INDENT : std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new (0);
7
8#[expect(clippy::missing_panics_doc)]
12pub fn write_info_system <W : std::io::Write>
13 (writer : &mut W, system : &fmod::System) -> Result <(), std::io::Error>
14{
15 let indent = indent_string();
16 writeln!(writer, "{indent}# fmod system info #")?;
17 writeln!(writer, "{}{:<36} {}", indent, "fmod system: version:",
18 system.get_version_string().unwrap())?;
19 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: output:",
20 system.get_output().unwrap())?;
21 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: num drivers:",
22 system.get_num_drivers().unwrap())?;
23 for i in 0..system.get_num_drivers().unwrap() {
24 let driver_info = system.get_driver_info (i).unwrap();
25 writeln!(writer, "{indent}fmod system: driver info[{i}]:")?;
26 writeln!(writer, "{indent} {driver_info:?}")?;
27 }
28 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: record num drivers:",
29 system.get_record_num_drivers().unwrap())?;
30 for i in 0..system.get_record_num_drivers().unwrap().0 {
31 let (info, state) = system.get_record_driver_info (i).unwrap();
32 writeln!(writer, "{indent}fmod system: record driver info[{i}]:")?;
33 writeln!(writer, "{indent} {info:?}")?;
34 writeln!(writer, "{indent} {state:?}")?;
35 }
36 writeln!(writer, "{}{:<36} {}", indent, "fmod system: driver:",
37 system.get_driver().unwrap())?;
38 writeln!(writer, "{}{:<36} {}", indent, "fmod system: software channels:",
39 system.get_software_channels().unwrap())?;
40 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: channels playing:",
41 system.get_channels_playing().unwrap())?;
42 let (samplerate, speakermode, numrawspeakers) =
43 system.get_software_format().unwrap();
44 writeln!(writer, "{indent}fmod system: software format:")?;
45 writeln!(writer, "{indent} sample rate: {samplerate}")?;
46 writeln!(writer, "{indent} speaker mode: {speakermode:?}")?;
47 writeln!(writer, "{indent} num raw speakers: {numrawspeakers}")?;
48 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: dsp buffer size:",
49 system.get_dsp_buffer_size().unwrap())?;
50 writeln!(writer, "{indent}fmod system: speaker mode channels:")?;
52 for i in 0..fmod::Speakermode::MAX as u32 {
53 use fmod::FromPrimitive;
54 let mode = fmod::Speakermode::from_u32 (i).unwrap();
55 writeln!(writer, "{} {:?}: {}",
56 indent, mode, system.get_speaker_mode_channels (mode).unwrap())?;
57 }
58 writeln!(writer, "{indent}fmod system: num plugins:")?;
59 writeln!(writer, "{} Plugintype::Output: {:?}", indent,
60 system.get_num_plugins (fmod::Plugintype::Output).unwrap())?;
61 writeln!(writer, "{} Plugintype::Codec: {:?}", indent,
62 system.get_num_plugins (fmod::Plugintype::Codec).unwrap())?;
63 writeln!(writer, "{} Plugintype::DSP: {:?}", indent,
64 system.get_num_plugins (fmod::Plugintype::Dsp).unwrap())?;
65 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: output by plugin:",
67 system.get_output_by_plugin().unwrap())?;
68 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: 3d num listeners:",
69 system.get_3d_num_listeners().unwrap())?;
70 for i in 0..system.get_3d_num_listeners().unwrap() {
71 let attributes = system.get_3d_listener_attributes (i).unwrap();
72 writeln!(writer, "{indent}fmod system: 3d listener attributes[{i}]:")?;
73 writeln!(writer, "{} pos: {:?}", indent, attributes.pos)?;
74 writeln!(writer, "{} vel: {:?}", indent, attributes.vel)?;
75 writeln!(writer, "{} forward: {:?}", indent, attributes.forward)?;
76 writeln!(writer, "{} up: {:?}", indent, attributes.up)?;
77 }
78 writeln!(writer, "{indent}fmod system: 3d speaker position:")?;
79 let driver_id = system.get_driver().unwrap();
80 let driver_info = system.get_driver_info (driver_id).unwrap();
81 #[expect(clippy::cast_sign_loss)]
82 for i in 0..driver_info.speakermodechannels as u32 {
83 use fmod::FromPrimitive;
84 let speaker = fmod::Speaker::from_u32 (i).unwrap();
85 writeln!(writer, "{} {:?}: {:?}",
86 indent, speaker, system.get_speaker_position (speaker).unwrap())?;
87 }
88 let (doppler_scale, distance_factor, roll_off_scale) =
89 system.get_3d_settings().unwrap();
90 writeln!(writer, "{indent}fmod system: 3d settings:")?;
91 writeln!(writer, "{indent} doppler scale: {doppler_scale}")?;
92 writeln!(writer, "{indent} distance factor: {distance_factor}")?;
93 writeln!(writer, "{indent} roll off scale: {roll_off_scale}")?;
94 let (buffer_size, time_unit) = system.get_stream_buffer_size().unwrap();
95 writeln!(writer, "{}{:<36} ({}, {:?})", indent,
96 "fmod system: stream buffer size:", buffer_size, time_unit)?;
97 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: cpu usage:",
98 system.get_cpu_usage().unwrap())?;
99 writeln!(writer, "{}{:<36} {:?}", indent, "fmod system: sound ram:",
100 system.get_sound_ram().unwrap())?;
101 writeln!(writer, "{indent}fmod system: reverb properties:")?;
104 #[expect(clippy::cast_possible_wrap)]
105 for i in 0..fmod::dsp::REVERB_MAXINSTANCES as i32 {
106 writeln!(writer, "{indent} instance[{i}]:")?;
107 indent_bump (4);
108 let properties = show_reverb_properties (&system.get_reverb_properties (i)
109 .unwrap());
110 indent_unbump (4);
111 write!(writer, "{properties}")?;
112 }
113 writeln!(writer, "{}{:<36} {}", indent, "fmod system: geometry settings:",
115 system.get_geometry_settings().unwrap())?;
116 Ok(())
117} #[expect(clippy::missing_panics_doc)]
123pub fn write_info_reverb3d <W : std::io::Write>
124 (writer : &mut W, reverb : &fmod::Reverb3d) -> Result <(), std::io::Error>
125{
126 let indent = indent_string();
127 writeln!(writer, "{indent}# fmod reverb info #")?;
128 writeln!(writer, "{}fmod reverb: active: {}", indent,
129 reverb.get_active().unwrap())?;
130 let attributes = reverb.get_3d_attributes().unwrap();
131 writeln!(writer, "{indent}fmod reverb: 3d attributes:")?;
132 writeln!(writer, "{} position: {:?}", indent, attributes.position)?;
133 writeln!(writer, "{} min distance: {:?}", indent, attributes.mindistance)?;
134 writeln!(writer, "{} max distance: {:?}", indent, attributes.maxdistance)?;
135 write!(writer, "{}fmod reverb: properties: {}", indent,
136 show_reverb_properties (&reverb.get_properties().unwrap()))?;
137 Ok(())
138} #[expect(clippy::missing_panics_doc)]
144pub fn write_info_dsp <W : std::io::Write>
145 (writer : &mut W, dsp : &fmod::Dsp) -> Result <(), std::io::Error>
146{
147 let indent = indent_string();
148 writeln!(writer, "{indent}# fmod dsp info #")?;
149 writeln!(writer, "{}{:<24} {:?}", indent, "fmod dsp: type:",
150 dsp.get_type().unwrap())?;
151 writeln!(writer, "{}{:<24} {}", indent, "fmod dsp: active:",
152 dsp.get_active().unwrap())?;
153 writeln!(writer, "{}{:<24} {}", indent, "fmod dsp: bypass:",
155 dsp.get_bypass().unwrap())?;
156 writeln!(writer, "{}{:<24} {}", indent, "fmod dsp: num inputs:",
157 dsp.get_num_inputs().unwrap())?;
158 writeln!(writer, "{}{:<24} {}", indent, "fmod dsp: num outputs:",
159 dsp.get_num_outputs().unwrap())?;
160 Ok(())
164} #[expect(clippy::missing_panics_doc)]
170pub fn write_info_channel <W : std::io::Write> (
171 writer : &mut W,
172 channel : &fmod::Channel
173) -> Result <(), std::io::Error> {
174 let indent = indent_string();
175 writeln!(writer, "{indent}# fmod channel info #")?;
176 writeln!(writer, "{}{:<36} {}", indent, "fmod channel: index:",
177 channel.get_index().unwrap())?;
178 writeln!(writer, "{}{:<36} {}", indent, "fmod channel: channel group:",
179 channel.get_channel_group().unwrap().get_name().unwrap())?;
180 writeln!(writer, "{}{:<36} {}", indent, "fmod channel: priority:",
181 channel.get_priority().unwrap())?;
182 writeln!(writer, "{}{:<36} {}", indent, "fmod channel: is virtual:",
183 channel.is_virtual().unwrap())?;
184 writeln!(writer, "{}{:<36} {}", indent, "fmod channel: position (ms):",
185 channel.get_position (fmod::Timeunit::MS).unwrap())?;
186 writeln!(writer, "{}{:<36} {}", indent, "fmod channel: loop count:",
187 channel.get_loop_count().unwrap())?;
188 let (loop_start, loop_end) =
189 channel.get_loop_points (fmod::Timeunit::MS, fmod::Timeunit::MS).unwrap();
190 writeln!(writer, "{}{:<36} (start: {}, end: {})", indent,
191 "fmod channel: loop points (ms):", loop_start, loop_end)?;
192 writeln!(writer, "{}{:<36} {}", indent, "fmod channel: frequency:",
193 channel.get_frequency().unwrap())?;
194 writeln!(writer, "{indent}fmod channel: channel control:")?;
199 write_info_channel_control (writer, channel)?;
200 Ok(())
201} #[expect(clippy::missing_panics_doc)]
207pub fn write_info_channel_control <W : std::io::Write, C : ChannelControl> (
208 writer : &mut W,
209 control : &C
210) -> Result <(), std::io::Error> {
211 let indent = indent_string();
212 writeln!(writer, "{indent}# fmod channel control info #")?;
213 writeln!(writer, "{}{:<36} Mode({:b})", indent, "fmod channel control: mode:",
216 control.get_mode().unwrap())?;
217 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: is playing:",
218 control.is_playing().unwrap())?;
219 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: paused:",
220 control.get_paused().unwrap())?;
221 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: volume:",
222 control.get_volume().unwrap())?;
223 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: mute:",
224 control.get_mute().unwrap())?;
225 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: audibility:",
226 control.get_audibility().unwrap())?;
227 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: low pass gain:",
228 control.get_low_pass_gain().unwrap())?;
229 let delay = control.get_delay().unwrap();
230 writeln!(writer, "{}{:<36} {:?}", indent, "fmod channel control: delay:",
231 delay)?;
232 writeln!(writer, "{indent}fmod channel control: reverb properties (wet level):")?;
233 #[expect(clippy::cast_possible_wrap)]
234 for i in 0..fmod::dsp::REVERB_MAXINSTANCES as i32 {
235 writeln!(writer, "{} instance[{}]: {}",
236 indent, i, control.get_reverb_properties (i).unwrap())?;
237 }
238 let num_dsps = control.get_num_dsps().unwrap();
239 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: num dsps:",
240 num_dsps)?;
241 for i in 0..num_dsps {
242 writeln!(writer, "{indent}fmod channel control: dsp[{i}]:")?;
243 #[expect(clippy::cast_possible_wrap)]
244 let dsp = control.get_dsp (i as i32).unwrap();
245 indent_bump (4);
246 write_info_dsp (writer, &dsp)?;
247 indent_unbump (4);
248 }
249 match control.get_3d_attributes() {
250 Ok ((position, velocity)) => {
251 writeln!(writer, "{indent}fmod channel control: 3d attributes:")?;
252 writeln!(writer, "{indent} position: {position:?}")?;
253 writeln!(writer, "{indent} velocity: {velocity:?}")?;
254 writeln!(writer, "{}{:<36} {:?}", indent,
255 "fmod channel control: 3d min max distance:",
256 control.get_3d_min_max_distance().unwrap())?;
257 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: 3d spread:",
258 control.get_3d_spread().unwrap())?;
259 writeln!(writer, "{}{:<36} {}", indent, "fmod channel control: 3d doppler level:",
260 control.get_3d_doppler_level().unwrap())?;
261 writeln!(writer, "{}{:<36} {:?}", indent,
262 "fmod channel control: 3d custom rolloff:",
263 control.get_3d_custom_rolloff().unwrap())?;
264 writeln!(writer, "{}{:<36} {:?}", indent,
265 "fmod channel control: 3d distance filter:",
266 control.get_3d_distance_filter().unwrap())?;
267 writeln!(writer, "{}{:<36} {:?}", indent,
268 "fmod channel control: 3d occlusion:",
269 control.get_3d_occlusion().unwrap())?;
270 writeln!(writer, "{}{:<36} {:?}", indent,
271 "fmod channel control: 3d cone orientation:",
272 control.get_3d_cone_orientation().unwrap())?;
273 let (inside_cone_angle, outside_cone_angle, outside_volume) =
274 control.get_3d_cone_settings().unwrap();
275 writeln!(writer, "{indent}fmod channel control: 3d cone settings:")?;
276 writeln!(writer, "{indent} inside cone angle: {inside_cone_angle}")?;
277 writeln!(writer, "{indent} outside cone angle: {outside_cone_angle}")?;
278 writeln!(writer, "{indent} outside volume: {outside_volume}")?;
279 }
280 Err (fmod::Error::Needs3d) => {}
281 err => {
282 writeln!(writer, "channel control 3d attributes error: {err:?}")?;
283 unreachable!()
284 }
285 }
286 Ok (())
287}
288
289#[expect(clippy::missing_panics_doc)]
293pub fn write_info_channel_group <W : std::io::Write> (
294 writer : &mut W,
295 group : &fmod::ChannelGroup
296) -> Result <(), std::io::Error> {
297 let indent = indent_string();
298 writeln!(writer, "{indent}# fmod channel group info #")?;
299 writeln!(writer, "{}{:<40} {}", indent, "fmod channel group: name:",
300 group.get_name().unwrap())?;
301 writeln!(writer, "{}{:<40} {}", indent, "fmod channel group: is master:",
302 group.is_master().unwrap())?;
303 if let Ok (Some (parent_group)) = group.get_parent_group() {
304 writeln!(writer, "{}{:<40} {}", indent, "fmod channel group: parent group:",
305 parent_group.get_name().unwrap())?;
306 }
307 let num_groups = group.get_num_groups().unwrap();
308 writeln!(writer, "{}{:<40} {}", indent, "fmod channel group: num groups:",
309 num_groups)?;
310 let num_channels = group.get_num_channels().unwrap();
319 writeln!(writer, "{}{:<40} {}", indent, "fmod channel group: num channels:",
320 num_channels)?;
321 for i in 0..num_channels {
322 writeln!(writer, "{indent}fmod channel group: channel[{i}]:")?;
323 indent_bump (4);
324 write_info_channel (writer, &group.get_channel (i).unwrap())?;
325 indent_unbump (4);
326 }
327 writeln!(writer, "{indent}fmod channelgroup: channel control:")?;
328 write_info_channel_control (writer, group)?;
329 Ok(())
330} #[expect(clippy::missing_panics_doc)]
336pub fn write_info_sound <W : std::io::Write> (
337 writer : &mut W,
338 sound : &fmod::Sound
339) -> Result <(), std::io::Error> {
340 let indent = indent_string();
341 writeln!(writer, "{indent}# fmod sound info #")?;
342 writeln!(writer, "{}{:<32} {}", indent, "fmod sound: name:",
343 sound.get_name().unwrap())?;
344 writeln!(writer, "{}{:<32} {}", indent, "fmod sound: length (ms):",
345 sound.get_length (fmod::Timeunit::MS).unwrap())?;
346 writeln!(writer, "{}{:<32} {:?}", indent, "fmod sound: format:",
347 sound.get_format().unwrap())?;
348 writeln!(writer, "{}{:<32} {}", indent, "fmod sound: num sub sounds:",
349 sound.get_num_sub_sounds().unwrap())?;
350 writeln!(writer, "{}{:<32} {:?}", indent, "fmod sound: num tags:",
352 sound.get_num_tags().unwrap())?;
353 writeln!(writer, "{}{:<32} {:?}", indent, "fmod sound: open state:",
355 sound.get_open_state().unwrap())?;
356 writeln!(writer, "{}{:<32} Mode({:b})", indent, "fmod sound: mode:",
357 sound.get_mode().unwrap())?;
358 writeln!(writer, "{}{:<32} {}", indent, "fmod sound: loop count:",
359 sound.get_loop_count().unwrap())?;
360 let (loop_start, loop_end) =
361 sound.get_loop_points (fmod::Timeunit::MS, fmod::Timeunit::MS).unwrap();
362 writeln!(writer, "{}{:<32} (start: {}, end: {})", indent,
363 "fmod sound: loop points (ms):",
364 loop_start, loop_end)?;
365 let (frequency, priority) = sound.get_defaults().unwrap();
372 writeln!(writer, "{indent}fmod sound: defaults:")?;
373 writeln!(writer, "{indent} frequency: {frequency}")?;
374 writeln!(writer, "{indent} priority: {priority}")?;
375 writeln!(writer, "{}{:<32} {}", indent, "fmod sound: num sync points:",
376 sound.get_num_sync_points().unwrap())?;
377 writeln!(writer, "{}{:<32} {:?}", indent, "fmod sound: 3d min max distance:",
379 sound.get_3d_min_max_distance().unwrap())?;
380 let (inside_cone_angle, outside_cone_angle, outside_volume)
381 = sound.get_3d_cone_settings().unwrap();
382 writeln!(writer, "{indent}fmod sound: 3d cone settings:")?;
383 writeln!(writer, "{indent} inside cone angle: {inside_cone_angle}")?;
384 writeln!(writer, "{indent} outside cone angle: {outside_cone_angle}")?;
385 writeln!(writer, "{indent} outside volume: {outside_volume}")?;
386 Ok(())
389} pub fn show_reverb_properties (reverb_properties : &fmod::reverb3d::Properties)
395 -> String
396{
397 use std::fmt::Write;
398 let indent = indent_string();
399 let mut s = String::new();
400 writeln!(s, "{indent}ReverbProperties {{").unwrap();
401 writeln!(s, "{} {:<22} {}", indent, "decay time:",
402 reverb_properties.decay_time).unwrap();
403 writeln!(s, "{} {:<22} {}", indent, "early delay:",
404 reverb_properties.early_delay).unwrap();
405 writeln!(s, "{} {:<22} {}", indent, "late delay:",
406 reverb_properties.late_delay).unwrap();
407 writeln!(s, "{} {:<22} {}", indent, "hf reference:",
408 reverb_properties.hf_reference).unwrap();
409 writeln!(s, "{} {:<22} {}", indent, "hf decay ratio:",
410 reverb_properties.hf_decay_ratio).unwrap();
411 writeln!(s, "{} {:<22} {}", indent, "diffusion:",
412 reverb_properties.diffusion).unwrap();
413 writeln!(s, "{} {:<22} {}", indent, "density:",
414 reverb_properties.density).unwrap();
415 writeln!(s, "{} {:<22} {}", indent, "low shelf frequency:",
416 reverb_properties.low_shelf_frequency).unwrap();
417 writeln!(s, "{} {:<22} {}", indent, "low shelf gain:",
418 reverb_properties.low_shelf_gain).unwrap();
419 writeln!(s, "{} {:<22} {}", indent, "high cut:",
420 reverb_properties.high_cut).unwrap();
421 writeln!(s, "{} {:<22} {}", indent, "early late mix:",
422 reverb_properties.early_late_mix).unwrap();
423 writeln!(s, "{} {:<22} {}", indent, "wet level:",
424 reverb_properties.wet_level).unwrap();
425 writeln!(s, "{indent}}}").unwrap();
426 s
427} fn indent_bump (spaces : u32) -> String {
433 INDENT.fetch_add (spaces, std::sync::atomic::Ordering::SeqCst);
434 indent_string()
435}
436
437fn indent_unbump (spaces : u32) -> String {
438 INDENT.fetch_sub (spaces, std::sync::atomic::Ordering::SeqCst);
439 indent_string()
440}
441
442fn indent_string () -> String {
443 use std::iter::FromIterator;
444 let indent = INDENT.load (std::sync::atomic::Ordering::SeqCst) as usize;
445 String::from_iter (std::iter::repeat_n (' ', indent))
446}
447
448fn _pretty_indent (d : &dyn std::fmt::Debug) -> String {
449 let indent = indent_string();
450 let s = format!("{d:#?}");
451 let mut lines = s.lines();
452 let first = lines.next().unwrap();
453 #[expect(clippy::format_collect)]
454 let mut rest : String = lines.map (|line| format!("{indent}{line}\n")).collect();
455 rest.pop().unwrap();
456 [first.to_string(), "\n".to_string(), rest].concat()
457}