servo_media_audio/
constant_source_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::{
9    AudioNodeEngine, AudioNodeType, AudioScheduledSourceNodeMessage, BlockInfo, ChannelInfo,
10    OnEndedCallback, ShouldPlay,
11};
12use crate::param::{Param, ParamType};
13
14#[derive(Copy, Clone, Debug, MallocSizeOf)]
15pub struct ConstantSourceNodeOptions {
16    pub offset: f32,
17}
18
19impl Default for ConstantSourceNodeOptions {
20    fn default() -> Self {
21        ConstantSourceNodeOptions { offset: 1. }
22    }
23}
24
25#[derive(AudioScheduledSourceNode, AudioNodeCommon)]
26pub(crate) struct ConstantSourceNode {
27    channel_info: ChannelInfo,
28    offset: Param,
29    start_at: Option<Tick>,
30    stop_at: Option<Tick>,
31    onended_callback: Option<OnEndedCallback>,
32}
33
34impl ConstantSourceNode {
35    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -> Self {
36        Self {
37            channel_info,
38            offset: Param::new(options.offset),
39            start_at: None,
40            stop_at: None,
41            onended_callback: None,
42        }
43    }
44
45    pub fn update_parameters(&mut self, info: &BlockInfo, tick: Tick) -> bool {
46        self.offset.update(info, tick)
47    }
48}
49
50impl AudioNodeEngine for ConstantSourceNode {
51    fn node_type(&self) -> AudioNodeType {
52        AudioNodeType::ConstantSourceNode
53    }
54
55    fn process(&mut self, mut inputs: Chunk, info: &BlockInfo) -> Chunk {
56        debug_assert!(inputs.is_empty());
57
58        inputs.blocks.push(Default::default());
59
60        let (start_at, stop_at) = match self.should_play_at(info.frame) {
61            ShouldPlay::No => {
62                return inputs;
63            },
64            ShouldPlay::Between(start, end) => (start, end),
65        };
66
67        {
68            inputs.blocks[0].explicit_silence();
69
70            let mut iter = inputs.blocks[0].iter();
71            let mut offset = self.offset.value();
72            while let Some(mut frame) = iter.next() {
73                let tick = frame.tick();
74                if tick < start_at {
75                    continue;
76                } else if tick > stop_at {
77                    break;
78                }
79                if self.update_parameters(info, frame.tick()) {
80                    offset = self.offset.value();
81                }
82                frame.mutate_with(|sample, _| *sample = offset);
83            }
84        }
85        inputs
86    }
87    fn input_count(&self) -> u32 {
88        0
89    }
90
91    fn get_param(&mut self, id: ParamType) -> &mut Param {
92        match id {
93            ParamType::Offset => &mut self.offset,
94            _ => panic!("Unknown param {:?} for the offset", id),
95        }
96    }
97    make_message_handler!(AudioScheduledSourceNode: handle_source_node_message);
98}