diff --git a/components/script/dom/pannernode.rs b/components/script/dom/pannernode.rs index 7f1909cdb50..ab1fea05db9 100644 --- a/components/script/dom/pannernode.rs +++ b/components/script/dom/pannernode.rs @@ -54,16 +54,29 @@ impl PannerNode { ) -> Fallible { 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) { + fn SetRefDistance(&self, val: Finite) -> 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::().message(AudioNodeMessage::PannerNode(msg)); + Ok(()) } // https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance fn MaxDistance(&self) -> Finite { @@ -241,8 +258,8 @@ impl PannerNodeMethods for PannerNode { } // https://webaudio.github.io/web-audio-api/#dom-pannernode-maxdistance fn SetMaxDistance(&self, val: Finite) -> 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) -> 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) -> Fallible<()> { - if *val < 0. || *val > 360. { + if *val < 0. || *val > 1. { return Err(Error::InvalidState) } self.cone_outer_gain.set(*val); diff --git a/components/script/dom/webidls/PannerNode.webidl b/components/script/dom/webidls/PannerNode.webidl index 18d01f52b11..b1c1cdfb68f 100644 --- a/components/script/dom/webidls/PannerNode.webidl +++ b/components/script/dom/webidls/PannerNode.webidl @@ -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; diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 725b7075bbf..871365683e8 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -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": [ diff --git a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html index 5475a6210b7..95e914a75f6 100644 --- a/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html +++ b/tests/wpt/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html @@ -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(