servo_media_audio/
constant_source_node.rs

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