makepad_audio_graph/
mixer.rs

1use {
2    crate::{
3        makepad_platform::*,
4        register_audio_component,
5        audio_traits::*
6    },
7};
8
9live_design!{
10    pub Mixer = {{Mixer}} {
11    }
12}
13
14//enum ToUI {}
15enum FromUI {}
16
17#[derive(Live)]
18struct Mixer {
19    #[rust] inputs: ComponentMap<LiveId, AudioComponentRef>,
20    #[rust] from_ui: FromUISender<FromUI>,
21}
22
23impl LiveRegister for Mixer{
24    fn live_register(cx: &mut Cx){
25        register_audio_component!(cx, Mixer)
26    }
27}
28            
29impl LiveHook for Mixer {
30    fn apply_value_instance(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
31        self.inputs.get_or_insert(cx, nodes[index].id, | cx | {AudioComponentRef::new(cx)})
32            .apply(cx, apply, index, nodes)
33    }
34    
35    fn after_apply(&mut self, _cx: &mut Cx, apply: &mut Apply, _index: usize, _nodes: &[LiveNode]) {
36        // so.. alright.. if we have a file_id we can gc the inputs
37        if apply.from.is_from_doc() {
38            self.inputs.retain_visible();
39        }
40    }
41}
42
43struct Node {
44    _from_ui: FromUIReceiver<FromUI>,
45    buffer: AudioBuffer,
46    inputs: Vec<Box<dyn AudioGraphNode + Send >>
47}
48
49// ok so how do we spawn this shit up.
50
51impl AudioGraphNode for Node {
52    fn all_notes_off(&mut self) {
53        for i in 0..self.inputs.len() {
54            let input = &mut self.inputs[i];
55            input.all_notes_off();
56        }
57    }
58    
59    fn handle_midi_data(&mut self, data: MidiData) {
60        for input in &mut self.inputs {
61            input.handle_midi_data(data);
62        }
63    }
64    
65    fn render_to_audio_buffer(
66        &mut self,
67        info: AudioInfo,
68        outputs: &mut [&mut AudioBuffer],
69        _inputs: &[&AudioBuffer],
70        display: &mut DisplayAudioGraph
71    ) {
72        let output = &mut outputs[0];
73        self.buffer.resize_like(*output);
74        output.zero();
75        for i in 0..self.inputs.len() {
76            let input = &mut self.inputs[i];
77            input.render_to_audio_buffer(info, &mut [&mut self.buffer], &[], display);
78            for c in 0..output.channel_count() {
79                let out_channel = output.channel_mut(c);
80                let in_channel = self.buffer.channel(c);
81                for j in 0..out_channel.len() {
82                    out_channel[j] += in_channel[j]; //*0.1;
83                }
84            }
85        }
86    }
87}
88
89
90impl AudioComponent for Mixer {
91    fn get_graph_node(&mut self, cx: &mut Cx) -> Box<dyn AudioGraphNode + Send> {
92        
93        self.from_ui.new_channel();
94        let mut inputs = Vec::new();
95        for input in self.inputs.values_mut() {
96            if let Some(input) = input.as_mut() {
97                inputs.push(input.get_graph_node(cx));
98            }
99        }
100        Box::new(Node {
101            inputs,
102            buffer: AudioBuffer::default(),
103            _from_ui: self.from_ui.receiver()
104        })
105    }
106    
107    fn handle_event_with(&mut self, cx: &mut Cx, event: &Event, dispatch_action: &mut dyn FnMut(&mut Cx, AudioComponentAction)) {
108        for input in self.inputs.values_mut() {
109            if let Some(input) = input.as_mut() {
110                input.handle_event_with(cx, event, dispatch_action)
111            }
112        }
113    }
114    
115    fn audio_query(&mut self, query: &AudioQuery, callback: &mut Option<AudioQueryCb>) -> AudioResult {
116        for input in self.inputs.values_mut() {
117            input.audio_query(query, callback) ?;
118        }
119        AudioResult::not_found()
120    }
121    
122}
123