fmod/core/system/
builder.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 crate::{InitFlags, OutputType, SpeakerMode, System};
8use fmod_sys::*;
9use std::ffi::{c_int, c_uint, c_void};
10
11pub struct SystemBuilder {
12    pub(crate) system: *mut FMOD_SYSTEM,
13}
14
15unsafe impl Send for SystemBuilder {}
16unsafe impl Sync for SystemBuilder {}
17
18impl SystemBuilder {
19    /// Creates a new [`SystemBuilder`].
20    ///
21    /// # Safety
22    ///
23    /// This must be called first to create an FMOD System object before any other API calls (except for [`memory_initialize`](crate::memory_initialize) and [`debug_initialize`](crate::debug_initialize)).
24    /// Use this function to create 1 or multiple instances of FMOD System objects.
25    ///
26    /// Calls to [`SystemBuilder::new`] and [`System::release`] are not thread-safe.
27    /// Do not call these functions simultaneously from multiple threads at once.
28    pub unsafe fn new() -> Result<Self> {
29        let mut system = std::ptr::null_mut();
30        unsafe { FMOD_System_Create(&mut system, FMOD_VERSION).to_result()? };
31
32        Ok(SystemBuilder { system })
33    }
34
35    pub fn software_format(
36        &mut self,
37        sample_rate: c_int,
38        speaker_mode: SpeakerMode,
39        raw_speakers: c_int,
40    ) -> Result<&mut Self> {
41        unsafe {
42            FMOD_System_SetSoftwareFormat(
43                self.system,
44                sample_rate,
45                speaker_mode.into(),
46                raw_speakers,
47            )
48            .to_result()?;
49        };
50        Ok(self)
51    }
52
53    pub fn software_channels(&mut self, software_channels: c_int) -> Result<&mut Self> {
54        unsafe {
55            FMOD_System_SetSoftwareChannels(self.system, software_channels).to_result()?;
56        };
57        Ok(self)
58    }
59
60    pub fn dsp_buffer_size(
61        &mut self,
62        buffer_size: c_uint,
63        buffer_count: c_int,
64    ) -> Result<&mut Self> {
65        unsafe {
66            FMOD_System_SetDSPBufferSize(self.system, buffer_size, buffer_count).to_result()?;
67        };
68        Ok(self)
69    }
70
71    pub fn output(&mut self, kind: OutputType) -> Result<&mut Self> {
72        unsafe {
73            FMOD_System_SetOutput(self.system, kind.into()).to_result()?;
74        };
75        Ok(self)
76    }
77
78    pub fn output_by_plugin(&mut self, handle: c_uint) -> Result<&mut Self> {
79        unsafe {
80            FMOD_System_SetOutputByPlugin(self.system, handle).to_result()?;
81        };
82        Ok(self)
83    }
84
85    pub fn build(self, max_channels: c_int, flags: InitFlags) -> Result<System> {
86        unsafe { self.build_with_extra_driver_data(max_channels, flags, std::ptr::null_mut()) }
87    }
88
89    /// # Safety
90    ///
91    /// See the FMOD docs explaining driver data for more safety information.
92    pub unsafe fn build_with_extra_driver_data(
93        self,
94        max_channels: c_int,
95        flags: InitFlags,
96        driver_data: *mut c_void,
97    ) -> Result<System> {
98        unsafe {
99            FMOD_System_Init(self.system, max_channels, flags.bits(), driver_data).to_result()?;
100        }
101        Ok(System { inner: self.system })
102    }
103}