1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use block::Chunk;
use block::Tick;
use node::BlockInfo;
use node::{AudioNodeEngine, AudioScheduledSourceNodeMessage, OnEndedCallback};
use node::{AudioNodeType, ChannelInfo, ShouldPlay};
use param::{Param, ParamType};

#[derive(Copy, Clone, Debug)]
pub struct ConstantSourceNodeOptions {
    pub offset: f32,
}

impl Default for ConstantSourceNodeOptions {
    fn default() -> Self {
        ConstantSourceNodeOptions { offset: 1. }
    }
}

#[derive(AudioScheduledSourceNode, AudioNodeCommon)]
pub(crate) struct ConstantSourceNode {
    channel_info: ChannelInfo,
    offset: Param,
    start_at: Option<Tick>,
    stop_at: Option<Tick>,
    onended_callback: Option<OnEndedCallback>,
}

impl ConstantSourceNode {
    pub fn new(options: ConstantSourceNodeOptions, channel_info: ChannelInfo) -> Self {
        Self {
            channel_info,
            offset: Param::new(options.offset.into()),
            start_at: None,
            stop_at: None,
            onended_callback: None,
        }
    }

    pub fn update_parameters(&mut self, info: &BlockInfo, tick: Tick) -> bool {
        self.offset.update(info, tick)
    }
}

impl AudioNodeEngine for ConstantSourceNode {
    fn node_type(&self) -> AudioNodeType {
        AudioNodeType::ConstantSourceNode
    }

    fn process(&mut self, mut inputs: Chunk, info: &BlockInfo) -> Chunk {
        debug_assert!(inputs.len() == 0);

        inputs.blocks.push(Default::default());

        let (start_at, stop_at) = match self.should_play_at(info.frame) {
            ShouldPlay::No => {
                return inputs;
            }
            ShouldPlay::Between(start, end) => (start, end),
        };

        {
            inputs.blocks[0].explicit_silence();

            let mut iter = inputs.blocks[0].iter();
            let mut offset = self.offset.value();
            while let Some(mut frame) = iter.next() {
                let tick = frame.tick();
                if tick < start_at {
                    continue;
                } else if tick > stop_at {
                    break;
                }
                if self.update_parameters(info, frame.tick()) {
                    offset = self.offset.value();
                }
                frame.mutate_with(|sample, _| *sample = offset);
            }
        }
        inputs
    }
    fn input_count(&self) -> u32 {
        0
    }

    fn get_param(&mut self, id: ParamType) -> &mut Param {
        match id {
            ParamType::Offset => &mut self.offset,
            _ => panic!("Unknown param {:?} for the offset", id),
        }
    }
    make_message_handler!(AudioScheduledSourceNode: handle_source_node_message);
}