fmod/core/system/device_selection.rs
1// Copyright (c) 2024 Melody Madeline 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 lanyard::Utf8CString;
9use std::{ffi::c_int, mem::MaybeUninit};
10
11use crate::{FmodResultExt, Result};
12use crate::{Guid, OutputType, SpeakerMode, System, get_string};
13
14#[cfg(doc)]
15use crate::SystemBuilder;
16
17impl System {
18 #[allow(clippy::doc_markdown)]
19 /// Sets the type of output interface used to run the mixer.
20 ///
21 /// This function is typically used to select between different OS specific audio APIs which may have different features.
22 ///
23 /// It is only necessary to call this function if you want to specifically switch away from the default output mode for the operating system.
24 /// The most optimal mode is selected by default for the operating system.
25 ///
26 /// (Windows, UWP, GameCore, Android, MacOS, iOS, Linux Only) This function can be called from outside the builder.
27 ///
28 /// When using the Studio API, switching to an NRT (non-realtime) output type after FMOD is already initialized
29 /// will not behave correctly unless the Studio API was initialized with [`crate::studio::InitFlags::SYNCHRONOUS_UPDATE`].
30 pub fn set_output(&self, output_type: OutputType) -> Result<()> {
31 unsafe { FMOD_System_SetOutput(self.inner.as_ptr(), output_type.into()).to_result() }
32 }
33
34 /// Retrieves the type of output interface used to run the mixer.
35 pub fn get_output_type(&self) -> Result<OutputType> {
36 let mut output_type = 0;
37 unsafe {
38 FMOD_System_GetOutput(self.inner.as_ptr(), &raw mut output_type).to_result()?;
39 }
40 let output_type = output_type.try_into()?;
41 Ok(output_type)
42 }
43
44 /// Retrieves the number of output drivers available for the selected output type.
45 ///
46 /// If [`SystemBuilder::output`]/[`System::set_output`] has not been called,
47 /// this function will return the number of drivers available for the default output type.
48 /// A possible use for this function is to iterate through available sound devices for the current output type,
49 /// and use [`System::get_driver_info`] to get the device's name and other attributes.
50 pub fn get_driver_count(&self) -> Result<c_int> {
51 let mut count = 0;
52 unsafe {
53 FMOD_System_GetNumDrivers(self.inner.as_ptr(), &raw mut count).to_result()?;
54 }
55 Ok(count)
56 }
57
58 /// Retrieves identification information about a sound device specified by its index, and specific to the selected output mode.
59 pub fn get_driver_info(
60 &self,
61 id: c_int,
62 ) -> Result<(Utf8CString, Guid, c_int, SpeakerMode, c_int)> {
63 unsafe {
64 let mut guid = MaybeUninit::zeroed();
65 let mut system_rate = 0;
66 let mut speaker_mode = 0;
67 let mut speaker_mode_channels = 0;
68
69 let name = get_string(|name| {
70 FMOD_System_GetDriverInfo(
71 self.inner.as_ptr(),
72 id,
73 name.as_mut_ptr().cast(),
74 name.len() as c_int,
75 guid.as_mut_ptr(),
76 &raw mut system_rate,
77 &raw mut speaker_mode,
78 &raw mut speaker_mode_channels,
79 )
80 })?;
81
82 let guid = guid.assume_init().into();
83 let speaker_mode = speaker_mode.try_into()?;
84
85 Ok((name, guid, system_rate, speaker_mode, speaker_mode_channels))
86 }
87 }
88
89 /// Sets the output driver for the selected output type.
90 ///
91 /// When an output type has more than one driver available, this function can be used to select between them.
92 ///
93 /// When this function is called, the current driver will be shutdown and the newly selected driver will be initialized / started.
94 pub fn set_driver(&self, driver: c_int) -> Result<()> {
95 unsafe { FMOD_System_SetDriver(self.inner.as_ptr(), driver).to_result() }
96 }
97
98 /// Retrieves the output driver for the selected output type.
99 pub fn get_driver(&self) -> Result<c_int> {
100 let mut driver = 0;
101 unsafe {
102 FMOD_System_GetDriver(self.inner.as_ptr(), &raw mut driver).to_result()?;
103 }
104 Ok(driver)
105 }
106}