fmod_utils/
audition.rs

1//! FMOD System wrapper
2
3use log;
4use fmod::{self, ChannelControl};
5use vec_map::VecMap;
6
7use crate::{Sampler, Music, Voice, voice};
8
9/// A high-level interface to an FMOD System
10#[derive(Debug, PartialEq)]
11pub struct Audition {
12  pub system  : fmod::System,
13  pub sampler : Sampler,
14  pub music   : Music,
15  pub voices  : VecMap <Voice>
16}
17
18impl Audition {
19  /// Create with default FMOD system
20  pub fn new() -> Self {
21    Self::default()
22  }
23  /// Create with provided initialized FMOD system
24  #[inline]
25  pub fn with_system (system : fmod::System) -> Self {
26    let sampler = Sampler::new (&system);
27    let music   = Music::default();
28    let voices  = VecMap::new();
29    Audition { system, sampler, music, voices }
30  }
31  /// Sets the master volume on the master channel group
32  #[inline]
33  #[expect(clippy::missing_panics_doc)]
34  pub fn set_master_volume (&self, volume : f32) {
35    self.system.get_master_channel_group().unwrap().set_volume (volume).unwrap()
36  }
37  /// Load sound sample files with given filenames.
38  #[inline]
39  pub fn load_samples (&mut self, samples : VecMap <String>) {
40    self.sampler.load (samples);
41  }
42  /// Load sound sample files from memory.
43  #[inline]
44  pub fn load_samples_memory (&mut self, samples : VecMap <&[u8]>) {
45    self.sampler.load_memory (samples);
46  }
47  /// Load sound sample files from PCM data.
48  #[inline]
49  pub fn load_samples_pcm (&mut self, samples : VecMap <&[i16]>) {
50    self.sampler.load_pcm (samples);
51  }
52  /// Load standard MIDI files (.mid) with given soundfont file paths (.dls)
53  #[inline]
54  pub fn load_songs_midi (&mut self, songs : VecMap <(String, String)>) {
55    self.music = Music::load_midi (&mut self.system, songs);
56  }
57  /// Load standard MIDI files (.mid) from memory, with given soundfont file
58  /// paths (.dls)
59  #[inline]
60  pub fn load_songs_midi_memory (&mut self, songs : VecMap <(&[u8], String)>) {
61    self.music = Music::load_midi_memory (&mut self.system, songs);
62  }
63  #[expect(clippy::missing_panics_doc)]
64  pub fn new_voice (&mut self) -> voice::Id {
65    let z : voice::IndexType = 0;
66    for i in z.. {
67      if !self.voices.contains_key (i as usize) {
68        assert!(self.voices.insert (i as usize, Voice::default()).is_none());
69        return voice::Id (i)
70      }
71    }
72    unreachable!();
73  }
74  #[inline]
75  pub fn remove_voice (&mut self, voice_id : voice::Id) -> Option <Voice> {
76    self.voices.remove (voice_id.0 as usize)
77  }
78  /// Convennience method to call the `update()` method of the FMOD system
79  #[inline]
80  #[expect(clippy::missing_panics_doc)]
81  pub fn update (&mut self) {
82    self.system.update().unwrap();
83  }
84}
85
86impl Default for Audition {
87  fn default() -> Self {
88    let system = fmod::System::default().unwrap_or_else (|err|{
89      log::error!("failed to create FMOD system: {err:?}");
90      panic!()
91    });
92    Audition::with_system (system)
93  }
94}