fmod/core/system/information.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::{
9 ffi::{c_int, c_longlong, c_uint},
10 mem::MaybeUninit,
11 os::raw::c_void,
12};
13
14use crate::{CpuUsage, SpeakerMode, System};
15
16impl System {
17 /// Retrieves the FMOD version number.
18 ///
19 /// The version is a 32 bit hexadecimal value formatted as 16:8:8, with the upper 16 bits being the product version,
20 /// the middle 8 bits being the major version and the bottom 8 bits being the minor version.
21 /// For example a value of 0x00010203 is equal to 1.02.03.
22 ///
23 /// Compare against [`crate::VERSION`] to make sure crate and runtime library versions match.
24 pub fn get_version(&self) -> Result<c_uint> {
25 let mut version = 0;
26 unsafe {
27 FMOD_System_GetVersion(self.inner, &mut version).to_result()?;
28 }
29 Ok(version)
30 }
31
32 /// Retrieves an output type specific internal native interface.
33 ///
34 /// Reinterpret the returned handle based on the selected output type, not all types return something.
35 /// [`OutputType::WavWriter`] Pointer to stdio FILE is returned
36 /// [`OutputType::WavWriterNRT`] Pointer to stdio FILE is returned
37 /// [`OutputType::WASAPI`] Pointer to type `IAudioClient` is returned.
38 /// [`OutputType::Alsa`] Pointer to type `snd_pcm_t` is returned.
39 /// [`OutputType::CoreAudio`] Handle of type `AudioUnit` is returned.
40 /// [`OutputType::AudioOut`] Pointer to type int is returned. Handle returned from sceAudioOutOpen.
41 ///
42 ///
43 /// NOTE: Calling this function is safe, but doing anything with the returned pointer is not!!
44 pub fn get_output_handle(&self) -> Result<*mut c_void> {
45 let mut handle = std::ptr::null_mut();
46 unsafe {
47 FMOD_System_GetOutputHandle(self.inner, &mut handle).to_result()?;
48 }
49 Ok(handle)
50 }
51
52 /// Retrieves the number of currently playing Channels.
53 ///
54 /// For differences between real and virtual voices see the Virtual Voices guide for more information.
55 pub fn get_playing_channels(&self) -> Result<(c_int, c_int)> {
56 let mut channels = 0;
57 let mut real_channels = 0;
58 unsafe {
59 FMOD_System_GetChannelsPlaying(self.inner, &mut channels, &mut real_channels)
60 .to_result()?;
61 }
62 Ok((channels, real_channels))
63 }
64
65 /// Retrieves the amount of CPU used for different parts of the Core engine.
66 ///
67 /// For readability, the percentage values are smoothed to provide a more stable output.
68 pub fn get_cpu_usage(&self) -> Result<CpuUsage> {
69 let mut cpu_usage = MaybeUninit::zeroed();
70 unsafe {
71 FMOD_System_GetCPUUsage(self.inner, cpu_usage.as_mut_ptr()).to_result()?;
72 let cpu_usage = cpu_usage.assume_init().into();
73 Ok(cpu_usage)
74 }
75 }
76
77 /// Retrieves information about file reads.
78 ///
79 /// The values returned are running totals that never reset.
80 pub fn get_file_usage(&self) -> Result<(c_longlong, c_longlong, c_longlong)> {
81 let mut sample_read = 0;
82 let mut stream_read = 0;
83 let mut other_read = 0;
84 unsafe {
85 FMOD_System_GetFileUsage(
86 self.inner,
87 &mut sample_read,
88 &mut stream_read,
89 &mut other_read,
90 )
91 .to_result()?;
92 }
93 Ok((sample_read, stream_read, other_read))
94 }
95
96 /// Retrieves the default matrix used to convert from one speaker mode to another.
97 ///
98 /// The gain for source channel 's' to target channel 't' is `matrix[t * <number of source channels> + s]`.
99 ///
100 /// If '`source_mode`' or '`target_mode`' is [`SpeakerMode::Raw`], this function will return [`FMOD_RESULT::FMOD_ERR_INVALID_PARAM`].
101 /// The number of source channels can be found from [`System::get_speaker_mode_channels`].
102 // FIXME: do we take an out slice param?
103 pub fn get_default_mix_matrix(
104 &self,
105 source_mode: SpeakerMode,
106 target_mode: SpeakerMode,
107 ) -> Result<Vec<f32>> {
108 let source_channels = self.get_speaker_mode_channels(source_mode)?;
109 let target_channels = self.get_speaker_mode_channels(target_mode)?;
110 debug_assert!(source_channels <= FMOD_MAX_CHANNEL_WIDTH as c_int);
111 debug_assert!(target_channels <= FMOD_MAX_CHANNEL_WIDTH as c_int);
112 let mut matrix = vec![0.0; source_channels as usize * target_channels as usize];
113
114 unsafe {
115 FMOD_System_GetDefaultMixMatrix(
116 self.inner,
117 source_mode.into(),
118 target_mode.into(),
119 matrix.as_mut_ptr(),
120 source_channels,
121 )
122 .to_result()?;
123 }
124 Ok(matrix)
125 }
126
127 /// Retrieves the channel count for a given speaker mode.
128 pub fn get_speaker_mode_channels(&self, speaker_mode: SpeakerMode) -> Result<c_int> {
129 let mut channels = 0;
130 unsafe {
131 FMOD_System_GetSpeakerModeChannels(self.inner, speaker_mode.into(), &mut channels)
132 .to_result()?;
133 }
134 Ok(channels)
135 }
136}