diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs index 5a42b2c958e..0b56325f7d9 100644 --- a/components/script/dom/audiobuffer.rs +++ b/components/script/dom/audiobuffer.rs @@ -94,47 +94,33 @@ impl AudioBuffer { )) } + // Initialize the underlying channels data with initial data provided by + // the user or silence otherwise. #[allow(unsafe_code)] pub fn set_channels(&self, initial_data: Option<&[Vec]>) { - let global = self.global(); - let cx = global.get_cx(); - let _ac = JSAutoCompartment::new(cx, global.reflector().get_jsobject().get()); - let chans = self.js_channels.borrow_mut(); for channel in 0..self.number_of_channels { - rooted!(in (cx) let mut array = ptr::null_mut::()); - match initial_data { - Some(data) => { - let _ = unsafe { - Float32Array::create( - cx, - CreateWith::Slice(data[channel as usize].as_slice()), - array.handle_mut(), - ) - }; - }, - None => { - let _ = unsafe { - Float32Array::create( - cx, - CreateWith::Slice(&vec![0.; self.length as usize]), - array.handle_mut(), - ) - }; - }, - } - chans[channel as usize].set(array.get()); + (*self.shared_channels.borrow_mut()).buffers[channel as usize] = match initial_data { + Some(data) => data[channel as usize].clone(), + None => vec![0.; self.length as usize], + }; } } + pub fn get_channels(&self) -> ServoMediaAudioBuffer { + self.shared_channels.borrow().clone() + } + #[allow(unsafe_code)] unsafe fn restore_js_channel_data(&self, cx: *mut JSContext) -> bool { + let global = self.global(); + let _ac = JSAutoCompartment::new(cx, global.reflector().get_jsobject().get()); for (i, channel) in self.js_channels.borrow_mut().iter().enumerate() { if !channel.get().is_null() { // Already have data in JS array. continue; } - // Move the channel data from shared_channels to js_channels. + // Copy the channel data from shared_channels to js_channels. rooted!(in (cx) let mut array = ptr::null_mut::()); let shared_channel = &(*self.shared_channels.borrow_mut()).buffers[i]; if Float32Array::create(cx, CreateWith::Slice(shared_channel), array.handle_mut()) @@ -306,7 +292,9 @@ impl AudioBufferMethods for AudioBuffer { let bytes_to_copy = min(self.length - start_in_channel, source.len() as u32) as usize; let offset = start_in_channel as usize; unsafe { - array.update(&source.as_slice()[offset..offset + bytes_to_copy]); + let data = &source.as_slice()[offset..offset + bytes_to_copy]; + array.update(data); + (*self.shared_channels.borrow_mut()).buffers[channel_number as usize] = data.to_vec(); } } else { return Err(Error::IndexSize); diff --git a/components/script/dom/audiobuffersourcenode.rs b/components/script/dom/audiobuffersourcenode.rs index 3e7948fdb3e..e2056535386 100644 --- a/components/script/dom/audiobuffersourcenode.rs +++ b/components/script/dom/audiobuffersourcenode.rs @@ -72,7 +72,7 @@ impl AudioBufferSourceNode { f32::MIN, f32::MAX, ); - Ok(AudioBufferSourceNode { + let node = AudioBufferSourceNode { source_node, buffer: Default::default(), playback_rate: Dom::from_ref(&playback_rate), @@ -80,7 +80,15 @@ impl AudioBufferSourceNode { loop_enabled: Cell::new(options.loop_), loop_start: Cell::new(*options.loopStart), loop_end: Cell::new(*options.loopEnd), - }) + }; + if let Some(ref buffer) = options.buffer { + if let Some(ref buffer) = buffer { + if let Err(err) = node.SetBuffer(Some(&**buffer)) { + return Err(err); + } + } + } + Ok(node) } #[allow(unrooted_must_root)] @@ -119,11 +127,13 @@ impl AudioBufferSourceNodeMethods for AudioBufferSourceNode { if self.source_node.started() { if let Some(buffer) = self.buffer.get() { let buffer = buffer.acquire_contents(); - self.source_node - .node() - .message(AudioNodeMessage::AudioBufferSourceNode( - AudioBufferSourceNodeMessage::SetBuffer(buffer), - )); + if buffer.is_some() { + self.source_node + .node() + .message(AudioNodeMessage::AudioBufferSourceNode( + AudioBufferSourceNodeMessage::SetBuffer(buffer), + )); + } } } @@ -197,11 +207,13 @@ impl AudioBufferSourceNodeMethods for AudioBufferSourceNode { if let Some(buffer) = self.buffer.get() { let buffer = buffer.acquire_contents(); - self.source_node - .node() - .message(AudioNodeMessage::AudioBufferSourceNode( - AudioBufferSourceNodeMessage::SetBuffer(buffer), - )); + if buffer.is_some() { + self.source_node + .node() + .message(AudioNodeMessage::AudioBufferSourceNode( + AudioBufferSourceNodeMessage::SetBuffer(buffer), + )); + } } self.source_node .upcast::() @@ -212,7 +224,15 @@ impl AudioBufferSourceNodeMethods for AudioBufferSourceNode { impl<'a> From<&'a AudioBufferSourceOptions> for AudioBufferSourceNodeOptions { fn from(options: &'a AudioBufferSourceOptions) -> Self { Self { - buffer: None, + buffer: if let Some(ref buffer) = options.buffer { + if let Some(ref buffer) = buffer { + Some(buffer.get_channels()) + } else { + None + } + } else { + None + }, detune: *options.detune, loop_enabled: options.loop_, loop_end: Some(*options.loopEnd), diff --git a/components/script/dom/webidls/AudioBufferSourceNode.webidl b/components/script/dom/webidls/AudioBufferSourceNode.webidl index a91a6afc393..bd8b4f5b0ae 100644 --- a/components/script/dom/webidls/AudioBufferSourceNode.webidl +++ b/components/script/dom/webidls/AudioBufferSourceNode.webidl @@ -7,7 +7,7 @@ */ dictionary AudioBufferSourceOptions { -// AudioBuffer? buffer; + AudioBuffer? buffer; float detune = 0; boolean loop = false; double loopEnd = 0;