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