fmod_utils/
sampler.rs

1//! Sample bank
2
3use fmod;
4use vec_map::VecMap;
5
6/// A vecmap of FMOD sounds.
7#[derive(Debug, PartialEq)]
8pub struct Sampler {
9  samples : VecMap <fmod::Sound>,
10  system  : fmod::System
11}
12
13pub type IndexType = u16;
14#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
15pub struct Id (pub IndexType);
16
17impl Sampler {
18  pub fn new (system : &fmod::System) -> Self {
19    Sampler {
20      samples: VecMap::new(),
21      system:  system.clone()
22    }
23  }
24
25  #[inline]
26  #[expect(clippy::missing_panics_doc)]
27  pub fn load (&mut self, files : VecMap <String>) {
28    let samples = files.into_iter().map (|(i, s)|
29      ( i,
30        self.system.create_sound_from_file (&s, fmod::Mode::DEFAULT, None).unwrap()
31      )
32    ).collect::<VecMap <fmod::Sound>>();
33    self.samples.extend (samples);
34  }
35  #[inline]
36  #[expect(clippy::missing_panics_doc)]
37  pub fn load_memory (&mut self, files : VecMap <&[u8]>) {
38    let samples = files.into_iter().map (|(i, bytes)|
39      ( i,
40        self.system.create_sound_from_memory (bytes, fmod::Mode::DEFAULT, None).unwrap()
41      )
42    ).collect::<VecMap <fmod::Sound>>();
43    self.samples.extend (samples);
44  }
45  #[inline]
46  #[expect(clippy::missing_panics_doc)]
47  pub fn load_pcm (&mut self, pcms : VecMap <&[i16]>) {
48    let samples = pcms.into_iter().map (|(i, pcm)|
49      ( i,
50        self.system.create_sound_from_pcm (pcm, fmod::Mode::DEFAULT, None).unwrap()
51      )
52    ).collect::<VecMap <fmod::Sound>>();
53    self.samples.extend (samples);
54  }
55  #[inline]
56  pub fn get (&self, id : Id) -> Option <&fmod::Sound> {
57    self.samples.get (id.0 as usize)
58  }
59  #[inline]
60  pub fn get_mut (&mut self, id : Id) -> Option <&mut fmod::Sound> {
61    self.samples.get_mut (id.0 as usize)
62  }
63  #[inline]
64  pub fn set (&mut self, sample : fmod::Sound, id : Id) {
65    let _ = self.samples.insert (id.0 as usize, sample);
66  }
67  #[inline]
68  pub fn remove (&mut self, id : Id) -> Option <fmod::Sound> {
69    self.samples.remove (id.0 as usize)
70  }
71  /// Start playing on a fresh channel; the priority system will "steal" an
72  /// existing channel if there are no free channels.
73  ///
74  /// If no mode is given, the current mode for the sound (`sound.get_mode()`)
75  /// will be used. Providing a mode will set the mode on the sound.
76  #[inline]
77  #[expect(clippy::missing_panics_doc)]
78  pub fn play (&mut self,
79    id            : Id,
80    mode          : Option <fmod::Mode>,
81    channel_group : Option <&mut fmod::ChannelGroup>
82  ) -> fmod::Channel {
83    let sample = self.samples.get_mut (id.0 as usize).unwrap();
84    mode.map (|mode| sample.set_mode (mode).unwrap());
85    sample.play (channel_group, false).unwrap()
86  }
87  /// "Play" on a fresh channel with 'paused = true'
88  #[inline]
89  #[expect(clippy::missing_panics_doc)]
90  pub fn cue (&mut self,
91    id            : Id,
92    mode          : Option <fmod::Mode>,
93    channel_group : Option <&mut fmod::ChannelGroup>
94  ) -> fmod::Channel {
95    let sample = self.samples.get_mut (id.0 as usize).unwrap();
96    mode.map (|mode| sample.set_mode (mode).unwrap());
97    sample.play (channel_group, true).unwrap()
98  }
99}
100
101impl Id {
102  #[inline]
103  pub const fn index (&self) -> usize {
104    self.0 as usize
105  }
106}