Skip to main content

fyrox_sound/effects/
mod.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! Contins everything related to audio effects that can be applied to an audio bus.
22
23use crate::{
24    effects::filter::{
25        AllPassFilterEffect, BandPassFilterEffect, HighPassFilterEffect, HighShelfFilterEffect,
26        LowPassFilterEffect, LowShelfFilterEffect,
27    },
28    effects::reverb::Reverb,
29};
30use fyrox_core::{reflect::prelude::*, uuid_provider, visitor::prelude::*};
31use strum_macros::{AsRefStr, EnumString, VariantNames};
32
33pub mod filter;
34pub mod reverb;
35
36/// Attenuation effect.
37#[derive(Debug, Clone, PartialEq, Visit, Reflect)]
38pub struct Attenuate {
39    gain: f32,
40}
41
42impl Default for Attenuate {
43    fn default() -> Self {
44        Self { gain: 1.0 }
45    }
46}
47
48impl Attenuate {
49    /// Creates new attenuation effect.
50    pub fn new(gain: f32) -> Self {
51        Self {
52            gain: gain.max(0.0),
53        }
54    }
55}
56
57impl EffectRenderTrait for Attenuate {
58    fn render(&mut self, input: &[(f32, f32)], output: &mut [(f32, f32)]) {
59        for ((input_left, input_right), (output_left, output_right)) in
60            input.iter().zip(output.iter_mut())
61        {
62            *output_left = *input_left * self.gain;
63            *output_right = *input_right * self.gain;
64        }
65    }
66}
67
68/// Effects is a digital signal processing (DSP) unit that transforms input signal in a specific way.
69/// For example, [`LowPassFilterEffect`] could be used to muffle audio sources; to create "underwater"
70/// effect.
71#[derive(Debug, Clone, PartialEq, Visit, Reflect, AsRefStr, EnumString, VariantNames)]
72pub enum Effect {
73    /// See [`Attenuate`] docs for more info.
74    Attenuate(Attenuate),
75    /// See [`Reverb`] docs for more info.
76    Reverb(Reverb),
77    /// See [`LowPassFilterEffect`] docs for more info.
78    LowPassFilter(LowPassFilterEffect),
79    /// See [`HighPassFilterEffect`] docs for more info.
80    HighPassFilter(HighPassFilterEffect),
81    /// See [`BandPassFilterEffect`] docs for more info.
82    BandPassFilter(BandPassFilterEffect),
83    /// See [`AllPassFilterEffect`] docs for more info.
84    AllPassFilter(AllPassFilterEffect),
85    /// See [`LowShelfFilterEffect`] docs for more info.
86    LowShelfFilter(LowShelfFilterEffect),
87    /// See [`HighShelfFilterEffect`] docs for more info.
88    HighShelfFilter(HighShelfFilterEffect),
89}
90
91uuid_provider!(Effect = "fc52e441-d1ec-4881-937c-9e2e53a6d621");
92
93impl Default for Effect {
94    fn default() -> Self {
95        Effect::Attenuate(Default::default())
96    }
97}
98
99pub(crate) trait EffectRenderTrait {
100    fn render(&mut self, input: &[(f32, f32)], output: &mut [(f32, f32)]);
101}
102
103macro_rules! static_dispatch {
104    ($self:ident, $func:ident, $($args:expr),*) => {
105        match $self {
106            Effect::Attenuate(v) => v.$func($($args),*),
107            Effect::Reverb(v) => v.$func($($args),*),
108            Effect::LowPassFilter(v) => v.$func($($args),*),
109            Effect::HighPassFilter(v) => v.$func($($args),*),
110            Effect::BandPassFilter(v) => v.$func($($args),*),
111            Effect::AllPassFilter(v) => v.$func($($args),*),
112            Effect::LowShelfFilter(v) => v.$func($($args),*),
113            Effect::HighShelfFilter(v) => v.$func($($args),*),
114        }
115    };
116}
117
118impl EffectRenderTrait for Effect {
119    fn render(&mut self, input: &[(f32, f32)], output: &mut [(f32, f32)]) {
120        static_dispatch!(self, render, input, output)
121    }
122}