Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix all AudioBuffer WPTs #21602

Merged
merged 10 commits into from Sep 19, 2018

Implement AudioBufferSourceOptions.AudioBuffer and always keep servo …

…media audio buffer updated
  • Loading branch information
ferjm committed Sep 19, 2018
commit e0e1f5f90035cf51e96f282f082fa9d90d7525f0
@@ -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<f32>]>) {
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::<JSObject>());
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::<JSObject>());
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);
@@ -72,15 +72,23 @@ impl AudioBufferSourceNode {
f32::MIN,
f32::MAX,
);
Ok(AudioBufferSourceNode {
let node = AudioBufferSourceNode {
source_node,
buffer: Default::default(),
playback_rate: Dom::from_ref(&playback_rate),
detune: Dom::from_ref(&detune),
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::<AudioScheduledSourceNode>()
@@ -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),
@@ -7,7 +7,7 @@
*/

dictionary AudioBufferSourceOptions {
// AudioBuffer? buffer;
AudioBuffer? buffer;
float detune = 0;
boolean loop = false;
double loopEnd = 0;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.