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