servo_media_audio/
constant_source_node.rs1use 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}