servo_media_audio/
gain_node.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use malloc_size_of_derive::MallocSizeOf;
6
7use crate::block::{Chunk, Tick};
8use crate::node::{AudioNodeEngine, AudioNodeType, BlockInfo, ChannelInfo};
9use crate::param::{Param, ParamType};
10
11#[derive(Copy, Clone, Debug, MallocSizeOf)]
12pub struct GainNodeOptions {
13    pub gain: f32,
14}
15
16impl Default for GainNodeOptions {
17    fn default() -> Self {
18        GainNodeOptions { gain: 1. }
19    }
20}
21
22#[derive(AudioNodeCommon)]
23pub(crate) struct GainNode {
24    channel_info: ChannelInfo,
25    gain: Param,
26}
27
28impl GainNode {
29    pub fn new(options: GainNodeOptions, channel_info: ChannelInfo) -> Self {
30        Self {
31            channel_info,
32            gain: Param::new(options.gain),
33        }
34    }
35
36    pub fn update_parameters(&mut self, info: &BlockInfo, tick: Tick) -> bool {
37        self.gain.update(info, tick)
38    }
39}
40
41impl AudioNodeEngine for GainNode {
42    fn node_type(&self) -> AudioNodeType {
43        AudioNodeType::GainNode
44    }
45
46    fn process(&mut self, mut inputs: Chunk, info: &BlockInfo) -> Chunk {
47        debug_assert!(inputs.len() == 1);
48
49        if inputs.blocks[0].is_silence() {
50            return inputs;
51        }
52
53        {
54            let mut iter = inputs.blocks[0].iter();
55            let mut gain = self.gain.value();
56
57            while let Some(mut frame) = iter.next() {
58                if self.update_parameters(info, frame.tick()) {
59                    gain = self.gain.value();
60                }
61                frame.mutate_with(|sample, _| *sample *= gain);
62            }
63        }
64        inputs
65    }
66
67    fn get_param(&mut self, id: ParamType) -> &mut Param {
68        match id {
69            ParamType::Gain => &mut self.gain,
70            _ => panic!("Unknown param {:?} for GainNode", id),
71        }
72    }
73}