Auto merge of #21555 - Manishearth:panner-node-ctor, r=ferjm

Throw errors for invalid values in panner node constructor

This was an oversight in the spec and is being fixed

https://github.com/WebAudio/web-audio-api/issues/1728

r? @ferjm

<!-- 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/21555)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-08-31 12:25:38 -04:00 committed by GitHub
commit 2351872354
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 10 deletions

View file

@ -54,16 +54,29 @@ impl PannerNode {
) -> Fallible<PannerNode> {
let count = options.parent.channelCount.unwrap_or(2);
let mode = options.parent.channelCountMode.unwrap_or(ChannelCountMode::Clamped_max);
let interpretation = options.parent.channelInterpretation.unwrap_or(ChannelInterpretation::Speakers);
if mode == ChannelCountMode::Max {
return Err(Error::NotSupported)
}
if count > 2 {
if count > 2 || count == 0 {
return Err(Error::NotSupported)
}
if *options.maxDistance <= 0. {
return Err(Error::Range("maxDistance should be positive".into()))
}
if *options.refDistance < 0. {
return Err(Error::Range("refDistance should be non-negative".into()))
}
if *options.rolloffFactor < 0. {
return Err(Error::Range("rolloffFactor should be non-negative".into()))
}
if *options.coneOuterGain < 0. || *options.coneOuterGain > 1. {
return Err(Error::InvalidState)
}
let mut node_options = AudioNodeOptions::empty();
node_options.channelCount = Some(count);
node_options.channelCountMode = Some(mode);
node_options.channelInterpretation = Some(ChannelInterpretation::Speakers);
node_options.channelInterpretation = Some(interpretation);
let options = options.into();
let node = AudioNode::new_inherited(
AudioNodeInit::PannerNode(options),
@ -230,10 +243,14 @@ impl PannerNodeMethods for PannerNode {
Finite::wrap(self.ref_distance.get())
}
// https://webaudio.github.io/web-audio-api/#dom-pannernode-refdistance
fn SetRefDistance(&self, val: Finite<f64>) {
fn SetRefDistance(&self, val: Finite<f64>) -> Fallible<()> {
if *val < 0. {
return Err(Error::Range("value should be non-negative".into()))
}
self.ref_distance.set(*val);
let msg = PannerNodeMessage::SetRefDistance(self.ref_distance.get());
self.upcast::<AudioNode>().message(AudioNodeMessage::PannerNode(msg));
Ok(())
}
// https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance
fn MaxDistance(&self) -> Finite<f64> {
@ -241,8 +258,8 @@ impl PannerNodeMethods for PannerNode {
}
// https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance
fn SetMaxDistance(&self, val: Finite<f64>) -> Fallible<()> {
if *val < 0. {
return Err(Error::NotSupported)
if *val <= 0. {
return Err(Error::Range("value should be positive".into()))
}
self.max_distance.set(*val);
let msg = PannerNodeMessage::SetMaxDistance(self.max_distance.get());
@ -256,7 +273,7 @@ impl PannerNodeMethods for PannerNode {
// https://webaudio.github.io/web-audio-api/#dom-pannernode-rollofffactor
fn SetRolloffFactor(&self, val: Finite<f64>) -> Fallible<()> {
if *val < 0. {
return Err(Error::Range("value should be positive".into()))
return Err(Error::Range("value should be non-negative".into()))
}
self.rolloff_factor.set(*val);
let msg = PannerNodeMessage::SetRolloff(self.rolloff_factor.get());
@ -289,7 +306,7 @@ impl PannerNodeMethods for PannerNode {
}
// https://webaudio.github.io/web-audio-api/#dom-pannernode-coneoutergain
fn SetConeOuterGain(&self, val: Finite<f64>) -> Fallible<()> {
if *val < 0. || *val > 360. {
if *val < 0. || *val > 1. {
return Err(Error::InvalidState)
}
self.cone_outer_gain.set(*val);

View file

@ -45,7 +45,7 @@ interface PannerNode : AudioNode {
readonly attribute AudioParam orientationY;
readonly attribute AudioParam orientationZ;
attribute DistanceModelType distanceModel;
attribute double refDistance;
[SetterThrows] attribute double refDistance;
[SetterThrows] attribute double maxDistance;
[SetterThrows] attribute double rolloffFactor;
attribute double coneInnerAngle;

View file

@ -647778,7 +647778,7 @@
"support"
],
"webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html": [
"5475a6210b724ab2d6a0cefedee9c5432953c61f",
"95e914a75f6784a76af79fcfce2e372ddb865814",
"testharness"
],
"webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html": [

View file

@ -192,6 +192,67 @@
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw(TypeError);
// Test maxDistance
options = {maxDistance: -1};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw(RangeError);
options = {maxDistance: 100};
should(
() => {
node = new PannerNode(context, options);
},
'node7 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.maxDistance, 'node7.maxDistance')
.beEqualTo(options.maxDistance);
// Test rolloffFactor
options = {rolloffFactor: -1};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw(RangeError);
options = {rolloffFactor: 0.5};
should(
() => {
node = new PannerNode(context, options);
},
'node8 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.rolloffFactor, 'node8.rolloffFactor')
.beEqualTo(options.rolloffFactor);
// Test coneOuterGain
options = {coneOuterGain: -1};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw('InvalidStateError');
options = {coneOuterGain: 1.1};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw('InvalidStateError');
options = {coneOuterGain: 0.5};
should(
() => {
node = new PannerNode(context, options);
},
'node9 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.coneOuterGain, 'node9.coneOuterGain')
.beEqualTo(options.coneOuterGain);
task.done();
});
@ -218,7 +279,7 @@
rolloffFactor: 3 * Math.PI,
coneInnerAngle: 4 * Math.PI,
coneOuterAngle: 5 * Math.PI,
coneOuterGain: 6 * Math.PI
coneOuterGain: 0.1 * Math.PI
};
should(