Auto merge of #21602 - ferjm:audiobuffer.crash, r=Manishearth

Fix all AudioBuffer WPTs

- [X] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [X] There are tests for these changes

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21602)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-09-19 04:07:04 -04:00 committed by GitHub
commit 0866dabc42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 141 additions and 70 deletions

8
Cargo.lock generated
View file

@ -2027,7 +2027,7 @@ dependencies = [
"hashglobe 0.1.0", "hashglobe 0.1.0",
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mozjs 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "mozjs 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.20.0", "selectors 0.20.0",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2228,7 +2228,7 @@ dependencies = [
[[package]] [[package]]
name = "mozjs" name = "mozjs"
version = "0.9.0" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3027,7 +3027,7 @@ dependencies = [
"mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mozjs 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "mozjs 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1", "msg 0.0.1",
"net_traits 0.0.1", "net_traits 0.0.1",
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -4516,7 +4516,7 @@ dependencies = [
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f" "checksum mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f"
"checksum mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "45a8a18a41cfab0fde25cc2f43ea89064d211a0fbb33225b8ff93ab20406e0e7" "checksum mozangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "45a8a18a41cfab0fde25cc2f43ea89064d211a0fbb33225b8ff93ab20406e0e7"
"checksum mozjs 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc9dc067f7e480f29ee32612b2aa76498c81926270c8190b8fe956b519dd659" "checksum mozjs 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ece829d04e44055b25d373bc92c28a032b549073bea8a5e57ca1c4b355d8377f"
"checksum mozjs_sys 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ff07b0f0a2371dc08d75d55371ca311be67e1fdfa6c146fc8ad154c340f70c9" "checksum mozjs_sys 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ff07b0f0a2371dc08d75d55371ca311be67e1fdfa6c146fc8ad154c340f70c9"
"checksum mp3-metadata 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ab5f1d2693586420208d1200ce5a51cd44726f055b635176188137aff42c7de" "checksum mp3-metadata 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ab5f1d2693586420208d1200ce5a51cd44726f055b635176188137aff42c7de"
"checksum mp4parse 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7316728464443fe5793a805dde3257864e9690cf46374daff3ce93de1df2f254" "checksum mp4parse 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7316728464443fe5793a805dde3257864e9690cf46374daff3ce93de1df2f254"

View file

@ -77,7 +77,9 @@ impl AudioBuffer {
window: &Window, window: &Window,
options: &AudioBufferOptions, options: &AudioBufferOptions,
) -> Fallible<DomRoot<AudioBuffer>> { ) -> 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 < MIN_SAMPLE_RATE ||
*options.sampleRate > MAX_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)] #[allow(unsafe_code)]
pub fn set_channels(&self, initial_data: Option<&[Vec<f32>]>) { 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 { for channel in 0..self.number_of_channels {
rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); (*self.shared_channels.borrow_mut()).buffers[channel as usize] = match initial_data {
match initial_data { Some(data) => data[channel as usize].clone(),
Some(data) => { None => vec![0.; self.length as usize],
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());
} }
} }
pub fn get_channels(&self) -> ServoMediaAudioBuffer {
self.shared_channels.borrow().clone()
}
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe fn restore_js_channel_data(&self, cx: *mut JSContext) -> bool { 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() { for (i, channel) in self.js_channels.borrow_mut().iter().enumerate() {
if !channel.get().is_null() { if !channel.get().is_null() {
// Already have data in JS array. // 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; 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>()); rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>());
let shared_channel = (*self.shared_channels.borrow_mut()).buffers.remove(i); if Float32Array::create(
if Float32Array::create(cx, CreateWith::Slice(&shared_channel), array.handle_mut()) cx,
.is_err() CreateWith::Slice(&(*self.shared_channels.borrow_mut()).buffers[i]),
array.handle_mut(),
).is_err()
{ {
return false; return false;
} }
@ -182,8 +179,6 @@ impl AudioBuffer {
// data into js_channels ArrayBuffers in restore_js_channel_data. // data into js_channels ArrayBuffers in restore_js_channel_data.
} }
self.js_channels.borrow_mut().clear();
Some((*self.shared_channels.borrow()).clone()) Some((*self.shared_channels.borrow()).clone())
} }
} }
@ -237,7 +232,11 @@ impl AudioBufferMethods for AudioBuffer {
channel_number: u32, channel_number: u32,
start_in_channel: u32, start_in_channel: u32,
) -> Fallible<()> { ) -> 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); return Err(Error::IndexSize);
} }
@ -248,18 +247,16 @@ impl AudioBufferMethods for AudioBuffer {
let mut dest = Vec::with_capacity(destination.len()); let mut dest = Vec::with_capacity(destination.len());
// We either copy form js_channels or shared_channels. // We either copy form js_channels or shared_channels.
let js_channel = self.js_channels.borrow()[channel_number].get(); let js_channel = self.js_channels.borrow()[channel_number].get();
if !js_channel.is_null() { if !js_channel.is_null() {
typedarray!(in(cx) let array: Float32Array = js_channel); typedarray!(in(cx) let array: Float32Array = js_channel);
if let Ok(array) = array { if let Ok(array) = array {
let data = unsafe { array.as_slice() }; let data = unsafe { array.as_slice() };
dest.extend_from_slice(&data[offset..offset + bytes_to_copy]); dest.extend_from_slice(&data[offset..offset + bytes_to_copy]);
return Ok(());
} }
} } else if let Some(shared_channel) =
self.shared_channels.borrow().buffers.get(channel_number)
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]); dest.extend_from_slice(&shared_channel.as_slice()[offset..offset + bytes_to_copy]);
} }
@ -278,6 +275,10 @@ impl AudioBufferMethods for AudioBuffer {
channel_number: u32, channel_number: u32,
start_in_channel: u32, start_in_channel: u32,
) -> Fallible<()> { ) -> 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) { if channel_number >= self.number_of_channels || start_in_channel > (source.len() as u32) {
return Err(Error::IndexSize); return Err(Error::IndexSize);
} }
@ -293,12 +294,23 @@ impl AudioBufferMethods for AudioBuffer {
return Err(Error::IndexSize); return Err(Error::IndexSize);
} }
typedarray!(in(cx) let array: Float32Array = js_channel); typedarray!(in(cx) let js_channel: Float32Array = js_channel);
if let Ok(mut array) = array { 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 bytes_to_copy = min(self.length - start_in_channel, source.len() as u32) as usize;
let offset = start_in_channel as usize;
unsafe { 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 { } else {
return Err(Error::IndexSize); return Err(Error::IndexSize);

View file

@ -72,7 +72,7 @@ impl AudioBufferSourceNode {
f32::MIN, f32::MIN,
f32::MAX, f32::MAX,
); );
Ok(AudioBufferSourceNode { let node = AudioBufferSourceNode {
source_node, source_node,
buffer: Default::default(), buffer: Default::default(),
playback_rate: Dom::from_ref(&playback_rate), playback_rate: Dom::from_ref(&playback_rate),
@ -80,7 +80,15 @@ impl AudioBufferSourceNode {
loop_enabled: Cell::new(options.loop_), loop_enabled: Cell::new(options.loop_),
loop_start: Cell::new(*options.loopStart), loop_start: Cell::new(*options.loopStart),
loop_end: Cell::new(*options.loopEnd), 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)] #[allow(unrooted_must_root)]
@ -119,11 +127,13 @@ impl AudioBufferSourceNodeMethods for AudioBufferSourceNode {
if self.source_node.started() { if self.source_node.started() {
if let Some(buffer) = self.buffer.get() { if let Some(buffer) = self.buffer.get() {
let buffer = buffer.acquire_contents(); let buffer = buffer.acquire_contents();
self.source_node if buffer.is_some() {
.node() self.source_node
.message(AudioNodeMessage::AudioBufferSourceNode( .node()
AudioBufferSourceNodeMessage::SetBuffer(buffer), .message(AudioNodeMessage::AudioBufferSourceNode(
)); AudioBufferSourceNodeMessage::SetBuffer(buffer),
));
}
} }
} }
@ -197,11 +207,13 @@ impl AudioBufferSourceNodeMethods for AudioBufferSourceNode {
if let Some(buffer) = self.buffer.get() { if let Some(buffer) = self.buffer.get() {
let buffer = buffer.acquire_contents(); let buffer = buffer.acquire_contents();
self.source_node if buffer.is_some() {
.node() self.source_node
.message(AudioNodeMessage::AudioBufferSourceNode( .node()
AudioBufferSourceNodeMessage::SetBuffer(buffer), .message(AudioNodeMessage::AudioBufferSourceNode(
)); AudioBufferSourceNodeMessage::SetBuffer(buffer),
));
}
} }
self.source_node self.source_node
.upcast::<AudioScheduledSourceNode>() .upcast::<AudioScheduledSourceNode>()
@ -212,7 +224,15 @@ impl AudioBufferSourceNodeMethods for AudioBufferSourceNode {
impl<'a> From<&'a AudioBufferSourceOptions> for AudioBufferSourceNodeOptions { impl<'a> From<&'a AudioBufferSourceOptions> for AudioBufferSourceNodeOptions {
fn from(options: &'a AudioBufferSourceOptions) -> Self { fn from(options: &'a AudioBufferSourceOptions) -> Self {
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, detune: *options.detune,
loop_enabled: options.loop_, loop_enabled: options.loop_,
loop_end: Some(*options.loopEnd), loop_end: Some(*options.loopEnd),

View file

@ -7,7 +7,7 @@
*/ */
dictionary AudioBufferSourceOptions { dictionary AudioBufferSourceOptions {
// AudioBuffer? buffer; AudioBuffer? buffer;
float detune = 0; float detune = 0;
boolean loop = false; boolean loop = false;
double loopEnd = 0; double loopEnd = 0;

View file

@ -1,2 +0,0 @@
[audiobuffer-copy-channel.html]
expected: CRASH

View file

@ -1,2 +0,0 @@
[ctor-audiobuffer.html]
expected: CRASH

View file

@ -1,2 +1,10 @@
[audiobuffersource-playbackrate-zero.html] [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

View file

@ -26,3 +26,6 @@
[# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.] [# AUDIT TASK RUNNER FINISHED: 1 out of 1 tasks were failed.]
expected: FAIL expected: FAIL
[< [Tests AudioBufferSourceNode start()\] 6 out of 18 assertions were failed.]
expected: FAIL

View file

@ -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] [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 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

View file

@ -1,2 +1,22 @@
[note-grain-on-play.html] [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

View file

@ -1,2 +0,0 @@
[audioparam-connect-audioratesignal.html]
expected: CRASH

View file

@ -1,2 +1,10 @@
[audioparam-summingjunction.html] [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