crayon_audio/
source.rs

1use crayon::math::prelude::Vector3;
2
3use assets::prelude::AudioClipHandle;
4
5impl_handle!(AudioSourceHandle);
6
7#[derive(Debug, Copy, Clone)]
8pub struct AudioSource {
9    /// Set the sound effect handle.
10    pub clip: AudioClipHandle,
11    /// Set the volume of a playing sound.
12    pub volume: f32,
13    /// Set the frequency-shift of a playing sound.
14    pub pitch: f32,
15    /// Set the wrap mode of playing sound.
16    pub loops: AudioSourceWrap,
17    /// Sets the spatial information of playing sound.
18    pub attenuation: Option<AudioSourceAttenuation>,
19}
20
21impl From<AudioClipHandle> for AudioSource {
22    fn from(clip: AudioClipHandle) -> Self {
23        AudioSource {
24            clip: clip,
25            volume: 1.0,
26            pitch: 1.0,
27            loops: AudioSourceWrap::Repeat(1),
28            attenuation: None,
29        }
30    }
31}
32
33/// The wrap mode of audio source.
34#[derive(Debug, Copy, Clone)]
35pub enum AudioSourceWrap {
36    Repeat(u32),
37    Infinite,
38}
39
40#[derive(Debug, Copy, Clone)]
41pub struct AudioSourceAttenuation {
42    /// Set the emiiter position of playing sound.
43    pub position: Vector3<f32>,
44    /// The minimum distance is the distance under which the sound will be
45    /// heard at its maximum volume.
46    pub minimum_distance: f32,
47    /// The attenuation is a multiplicative factor. The greater the attenuation,
48    /// the less it will be heard when the sound moves away from the listener.
49    ///
50    /// To get a non-attenuated sound, you can use 0.
51    pub attenuation: f32,
52}
53
54impl AudioSourceAttenuation {
55    pub fn new(minimum_distance: f32, attenuation: f32) -> Self {
56        assert!(minimum_distance > 0.0 && attenuation >= 0.0);
57
58        AudioSourceAttenuation {
59            position: Vector3::new(0.0, 0.0, 0.0),
60            minimum_distance: minimum_distance,
61            attenuation: attenuation,
62        }
63    }
64
65    pub fn volume<T>(&self, listener: T) -> f32
66    where
67        T: Into<Vector3<f32>>,
68    {
69        use crayon::math::prelude::InnerSpace;
70
71        let distance = (listener.into() - self.position)
72            .magnitude()
73            .max(self.minimum_distance);
74
75        let attenuation = self.attenuation * (distance - self.minimum_distance);
76        self.minimum_distance / (self.minimum_distance + attenuation)
77    }
78}