servo_media_audio/
gain_node.rs

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