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