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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use block::FRAMES_PER_BLOCK_USIZE;
use block::{Block, Chunk};
use node::AudioNodeType;
use node::BlockInfo;
use node::{AudioNodeEngine, ChannelCountMode, ChannelInfo, ChannelInterpretation};

#[derive(Copy, Clone, Debug)]
pub struct ChannelNodeOptions {
    pub channels: u8,
}

#[derive(AudioNodeCommon)]
pub(crate) struct ChannelMergerNode {
    channel_info: ChannelInfo,
    channels: u8,
}

impl ChannelMergerNode {
    pub fn new(params: ChannelNodeOptions, channel_info: ChannelInfo) -> Self {
        ChannelMergerNode {
            channel_info,
            channels: params.channels,
        }
    }
}

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

    fn process(&mut self, mut inputs: Chunk, _: &BlockInfo) -> Chunk {
        debug_assert!(inputs.len() == self.channels as usize);

        let mut block = Block::default();
        block.repeat(self.channels);
        block.explicit_repeat();

        for (i, channel) in block
            .data_mut()
            .chunks_mut(FRAMES_PER_BLOCK_USIZE)
            .enumerate()
        {
            channel.copy_from_slice(inputs.blocks[i].data_mut())
        }

        inputs.blocks.clear();
        inputs.blocks.push(block);
        inputs
    }

    fn input_count(&self) -> u32 {
        self.channels as u32
    }

    fn set_channel_count_mode(&mut self, _: ChannelCountMode) {
        panic!("channel merger nodes cannot have their mode changed");
    }

    fn set_channel_count(&mut self, _: u8) {
        panic!("channel merger nodes cannot have their channel count changed");
    }
}

#[derive(AudioNodeCommon)]
pub(crate) struct ChannelSplitterNode {
    channel_info: ChannelInfo,
}

impl ChannelSplitterNode {
    pub fn new(channel_info: ChannelInfo) -> Self {
        ChannelSplitterNode { channel_info }
    }
}

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

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

        let original = inputs.blocks.pop().unwrap();

        if original.is_silence() {
            inputs
                .blocks
                .resize(original.chan_count() as usize, Block::default())
        } else {
            for chan in 0..original.chan_count() {
                let mut block = Block::empty();
                block.push_chan(original.data_chan(chan));
                inputs.blocks.push(block);
            }
        }

        inputs
    }

    fn output_count(&self) -> u32 {
        self.channel_count() as u32
    }

    fn set_channel_count_mode(&mut self, _: ChannelCountMode) {
        panic!("channel splitter nodes cannot have their mode changed");
    }

    fn set_channel_interpretation(&mut self, _: ChannelInterpretation) {
        panic!("channel splitter nodes cannot have their channel interpretation changed");
    }

    fn set_channel_count(&mut self, _: u8) {
        panic!("channel splitter nodes cannot have their channel count changed");
    }
}