servo_media_audio/
media_element_source_node.rs

1use crate::block::{Block, Chunk, FRAMES_PER_BLOCK};
2use crate::node::{AudioNodeEngine, AudioNodeType, BlockInfo, ChannelInfo};
3use player::audio::AudioRenderer;
4use std::collections::hash_map::Entry;
5use std::collections::HashMap;
6use std::sync::mpsc::Sender;
7use std::sync::{Arc, Mutex};
8
9#[derive(Debug, Clone)]
10pub enum MediaElementSourceNodeMessage {
11    GetAudioRenderer(Sender<Arc<Mutex<dyn AudioRenderer>>>),
12}
13
14#[derive(AudioNodeCommon)]
15pub(crate) struct MediaElementSourceNode {
16    channel_info: ChannelInfo,
17    renderer: Arc<Mutex<dyn AudioRenderer>>,
18    buffers: Arc<Mutex<Vec<Vec<f32>>>>,
19    playback_offset: usize,
20}
21
22impl MediaElementSourceNode {
23    pub fn new(channel_info: ChannelInfo) -> Self {
24        let buffers = Arc::new(Mutex::new(Vec::new()));
25        let renderer = Arc::new(Mutex::new(MediaElementSourceNodeRenderer::new(
26            buffers.clone(),
27        )));
28        Self {
29            channel_info,
30            renderer,
31            buffers,
32            playback_offset: 0,
33        }
34    }
35
36    pub fn handle_message(&mut self, message: MediaElementSourceNodeMessage, _: f32) {
37        match message {
38            MediaElementSourceNodeMessage::GetAudioRenderer(sender) => {
39                let _ = sender.send(self.renderer.clone());
40            }
41        }
42    }
43}
44
45impl AudioNodeEngine for MediaElementSourceNode {
46    fn node_type(&self) -> AudioNodeType {
47        AudioNodeType::MediaElementSourceNode
48    }
49
50    fn process(&mut self, mut inputs: Chunk, _info: &BlockInfo) -> Chunk {
51        debug_assert!(inputs.len() == 0);
52
53        let buffers = self.buffers.lock().unwrap();
54        let chans = buffers.len() as u8;
55
56        if chans == 0 {
57            inputs.blocks.push(Default::default());
58            return inputs;
59        }
60
61        let len = buffers[0].len();
62
63        let frames_per_block = FRAMES_PER_BLOCK.0 as usize;
64        let samples_to_copy = if self.playback_offset + frames_per_block > len {
65            len - self.playback_offset
66        } else {
67            frames_per_block
68        };
69        let next_offset = self.playback_offset + samples_to_copy;
70        if samples_to_copy == FRAMES_PER_BLOCK.0 as usize {
71            // copy entire chan
72            let mut block = Block::empty();
73            for chan in 0..chans {
74                block.push_chan(&buffers[chan as usize][self.playback_offset..next_offset]);
75            }
76            inputs.blocks.push(block)
77        } else {
78            // silent fill and copy
79            let mut block = Block::default();
80            block.repeat(chans);
81            block.explicit_repeat();
82            for chan in 0..chans {
83                let data = block.data_chan_mut(chan);
84                let (_, data) = data.split_at_mut(0);
85                let (data, _) = data.split_at_mut(samples_to_copy);
86                data.copy_from_slice(&buffers[chan as usize][self.playback_offset..next_offset]);
87            }
88            inputs.blocks.push(block)
89        }
90
91        self.playback_offset = next_offset;
92
93        inputs
94    }
95
96    fn input_count(&self) -> u32 {
97        0
98    }
99
100    make_message_handler!(MediaElementSourceNode: handle_message);
101}
102
103struct MediaElementSourceNodeRenderer {
104    buffers: Arc<Mutex<Vec<Vec<f32>>>>,
105    channels: HashMap<u32, usize>,
106}
107
108impl MediaElementSourceNodeRenderer {
109    pub fn new(buffers: Arc<Mutex<Vec<Vec<f32>>>>) -> Self {
110        Self {
111            buffers,
112            channels: HashMap::new(),
113        }
114    }
115}
116
117impl AudioRenderer for MediaElementSourceNodeRenderer {
118    fn render(&mut self, sample: Box<dyn AsRef<[f32]>>, channel_pos: u32) {
119        let channel = match self.channels.entry(channel_pos) {
120            Entry::Occupied(entry) => *entry.get(),
121            Entry::Vacant(entry) => {
122                let mut buffers = self.buffers.lock().unwrap();
123                let len = buffers.len();
124                buffers.resize(len + 1, Vec::new());
125                *entry.insert(buffers.len())
126            }
127        };
128        self.buffers.lock().unwrap()[(channel - 1) as usize].extend_from_slice((*sample).as_ref());
129    }
130}