servo_media_audio/
constant_source_node.rs1use malloc_size_of_derive::MallocSizeOf;
6
7use crate::audio_node::{
8 AudioNodeEngine, AudioNodeType, AudioScheduledSourceNodeMessage, BlockInfo, ChannelInfo,
9 OnEndedCallback, ShouldPlay,
10};
11use crate::block::{Chunk, Tick};
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 self.update_parameters(info, frame.tick());
77 continue;
78 } else if tick >= stop_at {
79 break;
80 }
81 if self.update_parameters(info, frame.tick()) {
82 offset = self.offset.value();
83 }
84 frame.mutate_with(|sample, _| *sample = offset);
85 }
86 }
87 inputs
88 }
89 fn input_count(&self) -> u32 {
90 0
91 }
92
93 fn get_param(&mut self, id: ParamType) -> &mut Param {
94 match id {
95 ParamType::Offset => &mut self.offset,
96 _ => panic!("Unknown param {:?} for the offset", id),
97 }
98 }
99 make_message_handler!(AudioScheduledSourceNode: handle_source_node_message);
100}