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}