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

Some generated files are not rendered by default. Learn more.

@@ -77,7 +77,9 @@ impl AudioBuffer {
window: &Window,
options: &AudioBufferOptions,
) -> Fallible<DomRoot<AudioBuffer>> {
if options.numberOfChannels > MAX_CHANNEL_COUNT ||
if options.length <= 0 ||
options.numberOfChannels <= 0 ||
options.numberOfChannels > MAX_CHANNEL_COUNT ||
*options.sampleRate < MIN_SAMPLE_RATE ||
*options.sampleRate > MAX_SAMPLE_RATE
{
@@ -92,51 +94,46 @@ 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.
// We may have called GetChannelData, and web content may have modified
// js_channels. So make sure that shared_channels contains the same data as
// js_channels.
typedarray!(in(cx) let array: Float32Array = channel.get());
if let Ok(array) = array {
(*self.shared_channels.borrow_mut()).buffers[i] = array.to_vec();
}
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.remove(i);
if Float32Array::create(cx, CreateWith::Slice(&shared_channel), array.handle_mut())
.is_err()
if Float32Array::create(
cx,
CreateWith::Slice(&(*self.shared_channels.borrow_mut()).buffers[i]),
array.handle_mut(),
).is_err()
{
return false;
}
@@ -182,8 +179,6 @@ impl AudioBuffer {
// data into js_channels ArrayBuffers in restore_js_channel_data.
}

self.js_channels.borrow_mut().clear();

Some((*self.shared_channels.borrow()).clone())
}
}
@@ -237,7 +232,11 @@ impl AudioBufferMethods for AudioBuffer {
channel_number: u32,
start_in_channel: u32,
) -> Fallible<()> {
if channel_number >= self.number_of_channels || start_in_channel > self.length {
if destination.is_shared() {
return Err(Error::Type("Cannot copy to shared buffer".to_owned()));
}

if channel_number >= self.number_of_channels || start_in_channel >= self.length {
return Err(Error::IndexSize);
}

@@ -248,18 +247,16 @@ impl AudioBufferMethods for AudioBuffer {
let mut dest = Vec::with_capacity(destination.len());

// We either copy form js_channels or shared_channels.

let js_channel = self.js_channels.borrow()[channel_number].get();
if !js_channel.is_null() {
typedarray!(in(cx) let array: Float32Array = js_channel);
if let Ok(array) = array {
let data = unsafe { array.as_slice() };
dest.extend_from_slice(&data[offset..offset + bytes_to_copy]);
return Ok(());
}
}

if let Some(shared_channel) = self.shared_channels.borrow().buffers.get(channel_number) {
} else if let Some(shared_channel) =
self.shared_channels.borrow().buffers.get(channel_number)
{
dest.extend_from_slice(&shared_channel.as_slice()[offset..offset + bytes_to_copy]);
}

@@ -278,6 +275,10 @@ impl AudioBufferMethods for AudioBuffer {
channel_number: u32,
start_in_channel: u32,
) -> Fallible<()> {
if source.is_shared() {
return Err(Error::Type("Cannot copy from shared buffer".to_owned()));
}

if channel_number >= self.number_of_channels || start_in_channel > (source.len() as u32) {
return Err(Error::IndexSize);
}
@@ -293,12 +294,23 @@ impl AudioBufferMethods for AudioBuffer {
return Err(Error::IndexSize);
}

typedarray!(in(cx) let array: Float32Array = js_channel);
if let Ok(mut array) = array {
typedarray!(in(cx) let js_channel: Float32Array = js_channel);
if let Ok(mut js_channel) = js_channel {
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()[0..bytes_to_copy];
// Update shared channel.
{
let mut shared_channels = self.shared_channels.borrow_mut();
let shared_channel = shared_channels.data_chan_mut(channel_number as u8);
let (_, mut shared_channel) =
shared_channel.split_at_mut(start_in_channel as usize);
shared_channel[0..bytes_to_copy].copy_from_slice(data);
}
// Update js channel.
js_channel.update(
self.shared_channels.borrow().buffers[channel_number as usize].as_slice(),
);
}
} 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;

This file was deleted.

This file was deleted.

@@ -1,2 +1,10 @@
[audiobuffersource-playbackrate-zero.html]
expected: CRASH
[< [synthesize-verify\] 1 out of 1 assertions were failed.]
expected: FAIL

[X The zero playbackRate should hold the sample value. Expected 0.5 but got 0.5001220703125 at the index 4097 Got false.]
expected: FAIL

[# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.]
expected: FAIL

@@ -26,3 +26,6 @@
[# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.]
expected: FAIL

[< [Tests AudioBufferSourceNode start()\] 6 out of 18 assertions were failed.]
expected: FAIL

@@ -14,3 +14,9 @@
[X Interpolated sine wave does not equal [0,0.05756402388215065,0.11493714898824692,0.17192909121513367,0.22835086286067963,0.28401535749435425,0.3387379050254822,0.3923371136188507,0.44463518261909485,0.4954586327075958,0.5446390509605408,0.5920131802558899,0.6374239921569824,0.680720865726471,0.7217602133750916,0.760405957698822...\] with an element-wise tolerance of {"absoluteThreshold":0.090348,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[2\]\t0.0000000000000000e+0\t1.1493714898824692e-1\t1.1493714898824692e-1\t1.0000000000000000e+0\t9.0347999999999998e-2\n\t[3\]\t0.0000000000000000e+0\t1.7192909121513367e-1\t1.7192909121513367e-1\t1.0000000000000000e+0\t9.0347999999999998e-2\n\t[4\]\t0.0000000000000000e+0\t2.2835086286067963e-1\t2.2835086286067963e-1\t1.0000000000000000e+0\t9.0347999999999998e-2\n\t[5\]\t0.0000000000000000e+0\t2.8401535749435425e-1\t2.8401535749435425e-1\t1.0000000000000000e+0\t9.0347999999999998e-2\n\t[6\]\t0.0000000000000000e+0\t3.3873790502548218e-1\t3.3873790502548218e-1\t1.0000000000000000e+0\t9.0347999999999998e-2\n\t...and 477 more errors.\n\tMax AbsError of 1.0000000000000000e+0 at index of 300.\n\t[300\]\t0.0000000000000000e+0\t-1.0000000000000000e+0\t1.0000000000000000e+0\t1.0000000000000000e+0\t9.0347999999999998e-2\n\tMax RelError of 1.0000000000000000e+0 at index of 2.\n]
expected: FAIL

[X SNR (0.001829 dB) is not greater than or equal to 37.17. Got 0.0018292814994553732.]
expected: FAIL

[X Interpolated sine wave does not equal [0,0.05756402388215065,0.11493714898824692,0.17192909121513367,0.22835086286067963,0.28401535749435425,0.3387379050254822,0.3923371136188507,0.44463518261909485,0.4954586327075958,0.5446390509605408,0.5920131802558899,0.6374239921569824,0.680720865726471,0.7217602133750916,0.760405957698822...\] with an element-wise tolerance of {"absoluteThreshold":0.090348,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[0\]\t-1.6697746515274048e-1\t0.0000000000000000e+0\t1.6697746515274048e-1\tInfinity\t9.0347999999999998e-2\n\t[1\]\t-1.7548391222953796e-1\t5.7564023882150650e-2\t2.3304793611168861e-1\t4.0484997468002177e+0\t9.0347999999999998e-2\n\t[2\]\t-1.6324132680892944e-1\t1.1493714898824692e-1\t2.7817847579717636e-1\t2.4202660170874948e+0\t9.0347999999999998e-2\n\t[3\]\t-1.3169741630554199e-1\t1.7192909121513367e-1\t3.0362650752067566e-1\t1.7659984437464975e+0\t9.0347999999999998e-2\n\t[4\]\t-8.4581792354583740e-2\t2.2835086286067963e-1\t3.1293265521526337e-1\t1.3704027709594790e+0\t9.0347999999999998e-2\n\t...and 479 more errors.\n\tMax AbsError of 1.0805229544639587e+0 at index of 20.\n\t[20\]\t-1.6697746515274048e-1\t9.1354548931121826e-1\t1.0805229544639587e+0\t1.1827795847130018e+0\t9.0347999999999998e-2\n\tMax RelError of Infinity at index of 0.\n]
expected: FAIL

@@ -1,2 +1,22 @@
[note-grain-on-play.html]
expected: CRASH
[X Number of grains that started at the correct time is not equal to 100. Got 1.]
expected: FAIL

[X Pulse 0 boundary expected to be equal to the array [0,441\] but differs in 1 places:\n\tIndex\tActual\t\t\tExpected\n\t[1\]\t4.8520000000000000e+3\t4.4100000000000000e+2]
expected: FAIL

[X Number of start frames is not equal to 100. Got 1.]
expected: FAIL

[X Number of grains out of 100 that ended at the wrong time is not equal to 0. Got 1.]
expected: FAIL

[< [note-grain-on-play\] 5 out of 8 assertions were failed.]
expected: FAIL

[X Number of end frames is not equal to 100. Got 1.]
expected: FAIL

[# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.]
expected: FAIL

This file was deleted.

@@ -1,2 +1,10 @@
[audioparam-summingjunction.html]
expected: CRASH
[# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.]
expected: FAIL

[X Rendered signal matches sum of two audio-rate gain changing signals plus baseline gain is not true. Got false.]
expected: FAIL

[< [test\] 1 out of 2 assertions were failed.]
expected: FAIL

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.