<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[278961] trunk/LayoutTests/imported/w3c</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/278961">278961</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2021-06-16 15:37:01 -0700 (Wed, 16 Jun 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Resync webaudio tests from upstream WPT
https://bugs.webkit.org/show_bug.cgi?id=227091

Reviewed by Geoffrey Garen.

Resync webaudio tests from upstream WPT b5949c67c948bc452e3.

* web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-duration-loop.html:
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold-expected.txt: Added.
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html: Added.
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range-expected.txt: Added.
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range.html: Added.
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt:
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html:
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values-expected.txt:
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values.html:
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt:
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html:
* web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log:
* web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https-expected.txt: Added.
* web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https.html: Added.
* web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log:
* web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log:
* web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt:
* web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html:
* web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html:
* web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv-expected.txt:
* web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv.html:
* web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws-expected.txt: Added.
* web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws.html: Added.
* web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log:
* web-platform-tests/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudiobuffersourcenodeinterfaceaudiobuffersourcedurationloophtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-duration-loop.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamsetValueCurveexceptionsexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamsetValueCurveexceptionshtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfacecancelscheduledvaluesexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfacecancelscheduledvalueshtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceeventinsertionexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceeventinsertionhtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfacew3cimportlog">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioworkletinterfaceprocessorsw3cimportlog">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioworkletinterfacew3cimportlog">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithebiquadfilternodeinterfacebiquadautomationexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithebiquadfilternodeinterfacebiquadautomationhtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheconstantsourcenodeinterfacetestconstantsourcenodehtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheconvolvernodeinterfacerealtimeconvexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheconvolvernodeinterfacerealtimeconvhtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithepannernodeinterfacew3cimportlog">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheperiodicwaveinterfaceperiodicWavehtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamcancelandholdexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamcancelandholdhtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamnominalrangeexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamnominalrangehtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioworkletinterfaceaudioworkletthrowonmessagehttpsexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioworkletinterfaceaudioworkletthrowonmessagehttpshtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithepannernodeinterfacepannernodesetpositionthrowsexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithepannernodeinterfacepannernodesetpositionthrowshtml">trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/ChangeLog    2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -1,3 +1,38 @@
</span><ins>+2021-06-16  Chris Dumez  <cdumez@apple.com>
+
+        Resync webaudio tests from upstream WPT
+        https://bugs.webkit.org/show_bug.cgi?id=227091
+
+        Reviewed by Geoffrey Garen.
+
+        Resync webaudio tests from upstream WPT b5949c67c948bc452e3.
+
+        * web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-duration-loop.html:
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold-expected.txt: Added.
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html: Added.
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range-expected.txt: Added.
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range.html: Added.
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt:
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html:
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values-expected.txt:
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values.html:
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt:
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html:
+        * web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log:
+        * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https-expected.txt: Added.
+        * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https.html: Added.
+        * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log:
+        * web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log:
+        * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt:
+        * web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html:
+        * web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html:
+        * web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv-expected.txt:
+        * web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv.html:
+        * web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws-expected.txt: Added.
+        * web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws.html: Added.
+        * web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log:
+        * web-platform-tests/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html:
+
</ins><span class="cx"> 2021-06-16  Ada Chan  <ada.chan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Allow WebXR tests to be run on Mac
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudiobuffersourcenodeinterfaceaudiobuffersourcedurationloophtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-duration-loop.html (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-duration-loop.html        2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-duration-loop.html   2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -18,7 +18,7 @@
</span><span class="cx"> 
</span><span class="cx">         // Create the sample buffer and fill the second half with 1
</span><span class="cx">         let buffer = context.createBuffer(1, 2048, context.sampleRate);
</span><del>-        for(let i = 1024; i < 2048; i++) {
</del><ins>+        for (let i = 1024; i < 2048; i++) {
</ins><span class="cx">           buffer.getChannelData(0)[i] = 1;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -32,15 +32,17 @@
</span><span class="cx">         source.start(0, 1024 / context.sampleRate, 2048 / context.sampleRate);
</span><span class="cx">         // Expectations
</span><span class="cx">         let expected = new Float32Array(4096);
</span><del>-        for(let i = 0; i < 2048; i++) {
</del><ins>+        for (let i = 0; i < 2048; i++) {
</ins><span class="cx">           expected[i] = 1;
</span><span class="cx">         }
</span><span class="cx">         // Render it!
</span><span class="cx">         context.startRendering()
</span><del>-          .then(function(audioBuffer) {
-            should(audioBuffer.getChannelData, "audioBuffer.getChannelData").beEqualToArray(expected);
-          })
-          .then(task.done());
</del><ins>+            .then(function(audioBuffer) {
+              should(
+                  audioBuffer.getChannelData(0), 'audioBuffer.getChannelData')
+                  .beEqualToArray(expected);
+            })
+            .then(task.done());
</ins><span class="cx">       });
</span><span class="cx"> 
</span><span class="cx">       audit.run();
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamcancelandholdexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold-expected.txt (0 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold-expected.txt                                (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold-expected.txt   2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+
+PASS # AUDIT TASK RUNNER STARTED.
+PASS Executing "cancelTime"
+PASS Executing "linear"
+PASS Executing "exponential"
+PASS Executing "setTarget"
+PASS Executing "setValueCurve"
+PASS Executing "setValueCurve after end"
+PASS Executing "initial setTarget"
+PASS Executing "post cancel: Linear"
+PASS Executing "post cancel: Exponential"
+PASS Executing "post cancel: ValueCurve"
+PASS Executing "post cancel: setTarget"
+PASS Executing "post cancel: setValue"
+PASS Executing "cancel future setTarget"
+PASS Executing "cancel setTarget now"
+PASS Executing "cancel future setValueCurve"
+PASS Executing "cancel setValueCurve now"
+PASS Executing "linear, cancel, linear, cancel, linear"
+PASS Audit report
+PASS > [cancelTime] Test Invalid Values
+PASS   cancelAndHoldAtTime(-1) threw RangeError: "cancelTime must be a positive value".
+PASS   cancelAndHoldAtTime(NaN) threw TypeError: "The provided value is non-finite".
+PASS   cancelAndHoldAtTime(Infinity) threw TypeError: "The provided value is non-finite".
+PASS < [cancelTime] All assertions passed. (total 3 assertions)
+PASS > [linear] Cancel linearRampToValueAtTime
+PASS   linearRampToValueAtTime: linearRampToValue(0, 0.5) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0.000060,"relativeThreshold":0}.
+PASS   Cancelling linearRampToValueAtTime: linearRampToValue(0, 0.5) at time 0.25 contains only the constant 0.510204.
+PASS   Expected value for cancelling linearRampToValueAtTime: linearRampToValue(0, 0.5) at time 0.25 is 0.510204 within an error of 0.000084.
+PASS < [linear] All assertions passed. (total 3 assertions)
+PASS > [exponential] Cancel exponentialRampAtTime
+PASS   exponentialRampToValue(0.001, 0.5) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":5.9605e-8,"relativeThreshold":0}.
+PASS   Cancelling exponentialRampToValue(0.001, 0.5) at time 0.25 contains only the constant 0.033932.
+PASS   Expected value for cancelling exponentialRampToValue(0.001, 0.5) at time 0.25 is 0.033932 within an error of 0.000002.
+PASS < [exponential] All assertions passed. (total 3 assertions)
+PASS > [setTarget] Cancel setTargetAtTime
+PASS   setTargetAtTime(0, 0.01, 0.05) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS   Cancelling setTargetAtTime(0, 0.01, 0.05) at time 0.25 contains only the constant 0.008230.
+PASS   Expected value for cancelling setTargetAtTime(0, 0.01, 0.05) at time 0.25 is 0.008230 within an error of 4.5267e-7.
+PASS < [setTarget] All assertions passed. (total 3 assertions)
+PASS > [setValueCurve] Cancel setValueCurveAtTime
+PASS   setValueCurveAtTime([1,0], 0.01, 0.49) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS   Cancelling setValueCurveAtTime([1,0], 0.01, 0.49) at time 0.25 contains only the constant 0.510204.
+PASS   Expected value for cancelling setValueCurveAtTime([1,0], 0.01, 0.49) at time 0.25 is 0.510204 within an error of 9.5368e-9.
+PASS < [setValueCurve] All assertions passed. (total 3 assertions)
+PASS > [setValueCurve after end] Cancel setValueCurveAtTime after the end
+PASS   setValueCurveAtTime([1,0], 0.01, 0.115000) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS   Cancelling setValueCurveAtTime([1,0], 0.01, 0.115000) at time 0.25 contains only the constant 0.
+PASS   Expected value for cancelling setValueCurveAtTime([1,0], 0.01, 0.115000) at time 0.25 is 0 within an error of 0.
+PASS < [setValueCurve after end] All assertions passed. (total 3 assertions)
+PASS > [initial setTarget] Cancel with initial setTargetAtTime
+PASS   setTargetAtTime(0, 0.01, 0.1) up to time 0.25 equals [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1...] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS   Cancelling setTargetAtTime(0, 0.01, 0.1) at time 0.25 contains only the constant 0.090718.
+PASS   Expected value for cancelling setTargetAtTime(0, 0.01, 0.1) at time 0.25 is 0.090718 within an error of 0.000003.
+PASS < [initial setTarget] All assertions passed. (total 3 assertions)
+PASS > [post cancel: Linear] LinearRamp after cancelling
+PASS   Post cancellation linearRampToValueAtTime: linearRampToValue(0, 0.5) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":5.9605e-8,"relativeThreshold":0}.
+PASS   Cancelling Post cancellation linearRampToValueAtTime: linearRampToValue(0, 0.5) at time 0.25 contains only the constant 0.510204.
+PASS   Expected value for cancelling Post cancellation linearRampToValueAtTime: linearRampToValue(0, 0.5) at time 0.25 is 0.510204 within an error of 0.000084.
+PASS   Post linearRamp(2, 0.375) equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS < [post cancel: Linear] All assertions passed. (total 4 assertions)
+PASS > [post cancel: Exponential] ExponentialRamp after cancelling
+PASS   Post cancel exponentialRampToValueAtTime: linearRampToValue(0, 0.5) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":5.9605e-8,"relativeThreshold":0}.
+PASS   Cancelling Post cancel exponentialRampToValueAtTime: linearRampToValue(0, 0.5) at time 0.25 contains only the constant 0.510204.
+PASS   Expected value for cancelling Post cancel exponentialRampToValueAtTime: linearRampToValue(0, 0.5) at time 0.25 is 0.510204 within an error of 0.000084.
+PASS   Post exponentialRamp(2, 0.375) equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS < [post cancel: Exponential] All assertions passed. (total 4 assertions)
+PASS > [post cancel: ValueCurve]
+PASS   Post cancel setValueCurveAtTime: linearRampToValue(0, 0.5) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":5.9605e-8,"relativeThreshold":0}.
+PASS   Cancelling Post cancel setValueCurveAtTime: linearRampToValue(0, 0.5) at time 0.25 contains only the constant 0.510204.
+PASS   Expected value for cancelling Post cancel setValueCurveAtTime: linearRampToValue(0, 0.5) at time 0.25 is 0.510204 within an error of 0.000084.
+PASS   Post setValueCurve([0.125,2], 0.375, 0.125) equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0.000084,"relativeThreshold":0}.
+PASS < [post cancel: ValueCurve] All assertions passed. (total 4 assertions)
+PASS > [post cancel: setTarget]
+PASS   Post cancel setTargetAtTime: linearRampToValue(0, 0.5) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":5.9605e-8,"relativeThreshold":0}.
+PASS   Cancelling Post cancel setTargetAtTime: linearRampToValue(0, 0.5) at time 0.25 contains only the constant 0.510204.
+PASS   Expected value for cancelling Post cancel setTargetAtTime: linearRampToValue(0, 0.5) at time 0.25 is 0.510204 within an error of 0.000084.
+PASS   Post setTargetAtTime(0.125, 0.375, 0.1) equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0.000084,"relativeThreshold":0}.
+PASS < [post cancel: setTarget] All assertions passed. (total 4 assertions)
+PASS > [post cancel: setValue]
+PASS   Post cancel setValueAtTime: linearRampToValue(0, 0.5) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":5.9605e-8,"relativeThreshold":0}.
+PASS   Cancelling Post cancel setValueAtTime: linearRampToValue(0, 0.5) at time 0.25 contains only the constant 0.510204.
+PASS   Expected value for cancelling Post cancel setValueAtTime: linearRampToValue(0, 0.5) at time 0.25 is 0.510204 within an error of 0.000084.
+PASS   Post setValueAtTime(0.125, 0.375) equals [0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125...] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS < [post cancel: setValue] All assertions passed. (total 4 assertions)
+PASS > [cancel future setTarget]
+PASS   After cancelling future setTarget event, output contains only the constant 0.5.
+PASS < [cancel future setTarget] All assertions passed. (total 1 assertions)
+PASS > [cancel setTarget now]
+PASS   After cancelling setTarget event starting now, output contains only the constant 0.5.
+PASS < [cancel setTarget now] All assertions passed. (total 1 assertions)
+PASS > [cancel future setValueCurve]
+PASS   After cancelling future setValueCurve event, output contains only the constant 0.5.
+PASS < [cancel future setValueCurve] All assertions passed. (total 1 assertions)
+PASS > [cancel setValueCurve now]
+PASS   After cancelling current setValueCurve event starting now, output contains only the constant 0.5.
+PASS < [cancel setValueCurve now] All assertions passed. (total 1 assertions)
+PASS > [linear, cancel, linear, cancel, linear] Schedules 3 linear ramps, cancelling 2 of them, so that we end up with 2 cancel events next to each other
+PASS   1st linearRamp: linearRampToValue(0, 0.5) up to time 0.25 equals [expected array] with an element-wise tolerance of {"absoluteThreshold":5.9605e-8,"relativeThreshold":0}.
+PASS   Cancelling 1st linearRamp: linearRampToValue(0, 0.5) at time 0.25 contains only the constant 0.510204.
+PASS   Expected value for cancelling 1st linearRamp: linearRampToValue(0, 0.5) at time 0.25 is 0.510204 within an error of 0.
+PASS   2nd linearRamp(2, 0.5) equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS   Cancelling 2nd linearRamp(2, 0.5) at time 0.375 contains only the constant 1.255102.
+PASS   Expected value for cancelling 2nd linearRamp(2, 0.5) at time 0.375 is 1.255102 within an error of 0.
+PASS   3rd linearRamp(0, 0.5) equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.
+PASS < [linear, cancel, linear, cancel, linear] All assertions passed. (total 7 assertions)
+PASS # AUDIT TASK RUNNER FINISHED: 17 tasks ran successfully.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamcancelandholdhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html (0 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html                                (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html   2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -0,0 +1,855 @@
</span><ins>+<!DOCTYPE html>
+<html>
+  <head>
+    <title>
+      Test CancelValuesAndHoldAtTime
+    </title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audio-param.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
+  </head>
+  <body>
+    <script id="layout-test-code">
+      let sampleRate = 48000;
+      let renderDuration = 0.5;
+
+      let audit = Audit.createTaskRunner();
+
+      audit.define(
+          {label: 'cancelTime', description: 'Test Invalid Values'},
+          (task, should) => {
+            let context = new OfflineAudioContext({
+              numberOfChannels: 1,
+              length: 1,
+              sampleRate: 8000
+            });
+
+            let src = new ConstantSourceNode(context);
+            src.connect(context.destination);
+
+            should(
+                () => src.offset.cancelAndHoldAtTime(-1),
+                'cancelAndHoldAtTime(-1)')
+                .throw(RangeError);
+
+            // These are TypeErrors because |cancelTime| is a
+            // double, not unrestricted double.
+            should(
+                () => src.offset.cancelAndHoldAtTime(NaN),
+                'cancelAndHoldAtTime(NaN)')
+                .throw(TypeError);
+
+            should(
+                () => src.offset.cancelAndHoldAtTime(Infinity),
+                'cancelAndHoldAtTime(Infinity)')
+                .throw(TypeError);
+
+            task.done();
+          });
+
+      // The first few tasks test the cancellation of each relevant automation
+      // function.  For the test, a simple linear ramp from 0 to 1 is used to
+      // start things off.  Then the automation to be tested is scheduled and
+      // cancelled.
+
+      audit.define(
+          {label: 'linear', description: 'Cancel linearRampToValueAtTime'},
+          function(task, should) {
+            cancelTest(should, linearRampTest('linearRampToValueAtTime'), {
+              valueThreshold: 8.3998e-5,
+              curveThreshold: 5.9605e-5
+            }).then(task.done.bind(task));
+          });
+
+      audit.define(
+          {label: 'exponential', description: 'Cancel exponentialRampAtTime'},
+          function(task, should) {
+            // Cancel an exponential ramp.  The thresholds are experimentally
+            // determined.
+            cancelTest(should, function(g, v0, t0, cancelTime) {
+              // Initialize values to 0.
+              g[0].gain.setValueAtTime(0, 0);
+              g[1].gain.setValueAtTime(0, 0);
+              // Schedule a short linear ramp to start things off.
+              g[0].gain.linearRampToValueAtTime(v0, t0);
+              g[1].gain.linearRampToValueAtTime(v0, t0);
+
+              // After the linear ramp, schedule an exponential ramp to the end.
+              // (This is the event that will be be cancelled.)
+              let v1 = 0.001;
+              let t1 = renderDuration;
+
+              g[0].gain.exponentialRampToValueAtTime(v1, t1);
+              g[1].gain.exponentialRampToValueAtTime(v1, t1);
+
+              expectedConstant = Math.fround(
+                  v0 * Math.pow(v1 / v0, (cancelTime - t0) / (t1 - t0)));
+              return {
+                expectedConstant: expectedConstant,
+                autoMessage: 'exponentialRampToValue(' + v1 + ', ' + t1 + ')',
+                summary: 'exponentialRampToValueAtTime',
+              };
+            }, {
+              valueThreshold: 1.8664e-6,
+              curveThreshold: 5.9605e-8
+            }).then(task.done.bind(task));
+          });
+
+      audit.define(
+          {label: 'setTarget', description: 'Cancel setTargetAtTime'},
+          function(task, should) {
+            // Cancel a setTarget event.
+            cancelTest(should, function(g, v0, t0, cancelTime) {
+              // Initialize values to 0.
+              g[0].gain.setValueAtTime(0, 0);
+              g[1].gain.setValueAtTime(0, 0);
+              // Schedule a short linear ramp to start things off.
+              g[0].gain.linearRampToValueAtTime(v0, t0);
+              g[1].gain.linearRampToValueAtTime(v0, t0);
+
+              // At the end of the linear ramp, schedule a setTarget.  (This is
+              // the event that will be cancelled.)
+              let v1 = 0;
+              let t1 = t0;
+              let timeConstant = 0.05;
+
+              g[0].gain.setTargetAtTime(v1, t1, timeConstant);
+              g[1].gain.setTargetAtTime(v1, t1, timeConstant);
+
+              expectedConstant = Math.fround(
+                  v1 + (v0 - v1) * Math.exp(-(cancelTime - t0) / timeConstant));
+              return {
+                expectedConstant: expectedConstant,
+                autoMessage: 'setTargetAtTime(' + v1 + ', ' + t1 + ', ' +
+                    timeConstant + ')',
+                summary: 'setTargetAtTime',
+              };
+            }, {
+              valueThreshold: 4.5267e-7,  // 1.1317e-7,
+              curveThreshold: 0
+            }).then(task.done.bind(task));
+          });
+
+      audit.define(
+          {label: 'setValueCurve', description: 'Cancel setValueCurveAtTime'},
+          function(task, should) {
+            // Cancel a setValueCurve event.
+            cancelTest(should, function(g, v0, t0, cancelTime) {
+              // Initialize values to 0.
+              g[0].gain.setValueAtTime(0, 0);
+              g[1].gain.setValueAtTime(0, 0);
+              // Schedule a short linear ramp to start things off.
+              g[0].gain.linearRampToValueAtTime(v0, t0);
+              g[1].gain.linearRampToValueAtTime(v0, t0);
+
+              // After the linear ramp, schedule a setValuesCurve. (This is the
+              // event that will be cancelled.)
+              let v1 = 0;
+              let duration = renderDuration - t0;
+
+              // For simplicity, a 2-point curve so we get a linear interpolated
+              // result.
+              let curve = Float32Array.from([v0, 0]);
+
+              g[0].gain.setValueCurveAtTime(curve, t0, duration);
+              g[1].gain.setValueCurveAtTime(curve, t0, duration);
+
+              let index =
+                  Math.floor((curve.length - 1) / duration * (cancelTime - t0));
+
+              let curvePointsPerFrame =
+                  (curve.length - 1) / duration / sampleRate;
+              let virtualIndex =
+                  (cancelTime - t0) * sampleRate * curvePointsPerFrame;
+
+              let delta = virtualIndex - index;
+              expectedConstant = curve[0] + (curve[1] - curve[0]) * delta;
+              return {
+                expectedConstant: expectedConstant,
+                autoMessage: 'setValueCurveAtTime([' + curve + '], ' + t0 +
+                    ', ' + duration + ')',
+                summary: 'setValueCurveAtTime',
+              };
+            }, {
+              valueThreshold: 9.5368e-9,
+              curveThreshold: 0
+            }).then(task.done.bind(task));
+          });
+
+      audit.define(
+          {
+            label: 'setValueCurve after end',
+            description: 'Cancel setValueCurveAtTime after the end'
+          },
+          function(task, should) {
+            cancelTest(should, function(g, v0, t0, cancelTime) {
+              // Initialize values to 0.
+              g[0].gain.setValueAtTime(0, 0);
+              g[1].gain.setValueAtTime(0, 0);
+              // Schedule a short linear ramp to start things off.
+              g[0].gain.linearRampToValueAtTime(v0, t0);
+              g[1].gain.linearRampToValueAtTime(v0, t0);
+
+              // After the linear ramp, schedule a setValuesCurve. (This is the
+              // event that will be cancelled.)  Make sure the curve ends before
+              // the cancellation time.
+              let v1 = 0;
+              let duration = cancelTime - t0 - 0.125;
+
+              // For simplicity, a 2-point curve so we get a linear interpolated
+              // result.
+              let curve = Float32Array.from([v0, 0]);
+
+              g[0].gain.setValueCurveAtTime(curve, t0, duration);
+              g[1].gain.setValueCurveAtTime(curve, t0, duration);
+
+              expectedConstant = curve[1];
+              return {
+                expectedConstant: expectedConstant,
+                autoMessage: 'setValueCurveAtTime([' + curve + '], ' + t0 +
+                    ', ' + duration + ')',
+                summary: 'setValueCurveAtTime',
+              };
+            }, {
+              valueThreshold: 0,
+              curveThreshold: 0
+            }).then(task.done.bind(task));
+          });
+
+      // Special case where we schedule a setTarget and there is no earlier
+      // automation event.  This tests that we pick up the starting point
+      // correctly from the last setting of the AudioParam value attribute.
+
+
+      audit.define(
+          {
+            label: 'initial setTarget',
+            description: 'Cancel with initial setTargetAtTime'
+          },
+          function(task, should) {
+            cancelTest(should, function(g, v0, t0, cancelTime) {
+              let v1 = 0;
+              let timeConstant = 0.1;
+              g[0].gain.value = 1;
+              g[0].gain.setTargetAtTime(v1, t0, timeConstant);
+              g[1].gain.value = 1;
+              g[1].gain.setTargetAtTime(v1, t0, timeConstant);
+
+              let expectedConstant = Math.fround(
+                  v1 + (v0 - v1) * Math.exp(-(cancelTime - t0) / timeConstant));
+
+              return {
+                expectedConstant: expectedConstant,
+                autoMessage: 'setTargetAtTime(' + v1 + ', ' + t0 + ', ' +
+                    timeConstant + ')',
+                summary: 'Initial setTargetAtTime',
+              };
+            }, {
+              valueThreshold: 3.1210e-6,
+              curveThreshold: 0
+            }).then(task.done.bind(task));
+          });
+
+      // Test automations scheduled after the call to cancelAndHoldAtTime.
+      // Very similar to the above tests, but we also schedule an event after
+      // cancelAndHoldAtTime and verify that curve after cancellation has
+      // the correct values.
+
+      audit.define(
+          {
+            label: 'post cancel: Linear',
+            description: 'LinearRamp after cancelling'
+          },
+          function(task, should) {
+            // Run the cancel test using a linearRamp as the event to be
+            // cancelled. Then schedule another linear ramp after the
+            // cancellation.
+            cancelTest(
+                should,
+                linearRampTest('Post cancellation linearRampToValueAtTime'),
+                {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8},
+                function(g, cancelTime, expectedConstant) {
+                  // Schedule the linear ramp on g[0], and do the same for g[2],
+                  // using the starting point given by expectedConstant.
+                  let v2 = 2;
+                  let t2 = cancelTime + 0.125;
+                  g[0].gain.linearRampToValueAtTime(v2, t2);
+                  g[2].gain.setValueAtTime(expectedConstant, cancelTime);
+                  g[2].gain.linearRampToValueAtTime(v2, t2);
+                  return {
+                    constantEndTime: cancelTime,
+                    message: 'Post linearRamp(' + v2 + ', ' + t2 + ')'
+                  };
+                })
+                .then(task.done.bind(task));
+          });
+
+      audit.define(
+          {
+            label: 'post cancel: Exponential',
+            description: 'ExponentialRamp after cancelling'
+          },
+          function(task, should) {
+            // Run the cancel test using a linearRamp as the event to be
+            // cancelled. Then schedule an exponential ramp after the
+            // cancellation.
+            cancelTest(
+                should,
+                linearRampTest('Post cancel exponentialRampToValueAtTime'),
+                {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8},
+                function(g, cancelTime, expectedConstant) {
+                  // Schedule the exponential ramp on g[0], and do the same for
+                  // g[2], using the starting point given by expectedConstant.
+                  let v2 = 2;
+                  let t2 = cancelTime + 0.125;
+                  g[0].gain.exponentialRampToValueAtTime(v2, t2);
+                  g[2].gain.setValueAtTime(expectedConstant, cancelTime);
+                  g[2].gain.exponentialRampToValueAtTime(v2, t2);
+                  return {
+                    constantEndTime: cancelTime,
+                    message: 'Post exponentialRamp(' + v2 + ', ' + t2 + ')'
+                  };
+                })
+                .then(task.done.bind(task));
+          });
+
+      audit.define('post cancel: ValueCurve', function(task, should) {
+        // Run the cancel test using a linearRamp as the event to be cancelled.
+        // Then schedule a setValueCurve after the cancellation.
+        cancelTest(
+            should, linearRampTest('Post cancel setValueCurveAtTime'),
+            {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8},
+            function(g, cancelTime, expectedConstant) {
+              // Schedule the exponential ramp on g[0], and do the same for
+              // g[2], using the starting point given by expectedConstant.
+              let t2 = cancelTime + 0.125;
+              let duration = 0.125;
+              let curve = Float32Array.from([.125, 2]);
+              g[0].gain.setValueCurveAtTime(curve, t2, duration);
+              g[2].gain.setValueAtTime(expectedConstant, cancelTime);
+              g[2].gain.setValueCurveAtTime(curve, t2, duration);
+              return {
+                constantEndTime: cancelTime,
+                message: 'Post setValueCurve([' + curve + '], ' + t2 + ', ' +
+                    duration + ')',
+                errorThreshold: 8.3998e-5
+              };
+            })
+            .then(task.done.bind(task));
+      });
+
+      audit.define('post cancel: setTarget', function(task, should) {
+        // Run the cancel test using a linearRamp as the event to be cancelled.
+        // Then schedule a setTarget after the cancellation.
+        cancelTest(
+            should, linearRampTest('Post cancel setTargetAtTime'),
+            {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8},
+            function(g, cancelTime, expectedConstant) {
+              // Schedule the exponential ramp on g[0], and do the same for
+              // g[2], using the starting point given by expectedConstant.
+              let v2 = 0.125;
+              let t2 = cancelTime + 0.125;
+              let timeConstant = 0.1;
+              g[0].gain.setTargetAtTime(v2, t2, timeConstant);
+              g[2].gain.setValueAtTime(expectedConstant, cancelTime);
+              g[2].gain.setTargetAtTime(v2, t2, timeConstant);
+              return {
+                constantEndTime: cancelTime + 0.125,
+                message: 'Post setTargetAtTime(' + v2 + ', ' + t2 + ', ' +
+                    timeConstant + ')',
+                errorThreshold: 8.4037e-5
+              };
+            })
+            .then(task.done.bind(task));
+      });
+
+      audit.define('post cancel: setValue', function(task, should) {
+        // Run the cancel test using a linearRamp as the event to be cancelled.
+        // Then schedule a setTarget after the cancellation.
+        cancelTest(
+            should, linearRampTest('Post cancel setValueAtTime'),
+            {valueThreshold: 8.3998e-5, curveThreshold: 5.9605e-8},
+            function(g, cancelTime, expectedConstant) {
+              // Schedule the exponential ramp on g[0], and do the same for
+              // g[2], using the starting point given by expectedConstant.
+              let v2 = 0.125;
+              let t2 = cancelTime + 0.125;
+              g[0].gain.setValueAtTime(v2, t2);
+              g[2].gain.setValueAtTime(expectedConstant, cancelTime);
+              g[2].gain.setValueAtTime(v2, t2);
+              return {
+                constantEndTime: cancelTime + 0.125,
+                message: 'Post setValueAtTime(' + v2 + ', ' + t2 + ')'
+              };
+            })
+            .then(task.done.bind(task));
+      });
+
+      audit.define('cancel future setTarget', (task, should) => {
+        const context =
+            new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
+        const src = new ConstantSourceNode(context);
+        src.connect(context.destination);
+
+        src.offset.setValueAtTime(0.5, 0);
+        src.offset.setTargetAtTime(0, 0.75 * renderDuration, 0.1);
+        // Now cancel the effect of the setTarget.
+        src.offset.cancelAndHoldAtTime(0.5 * renderDuration);
+
+        src.start();
+        context.startRendering()
+            .then(buffer => {
+              let actual = buffer.getChannelData(0);
+              // Because the setTarget was cancelled, the output should be a
+              // constant.
+              should(actual, 'After cancelling future setTarget event, output')
+                  .beConstantValueOf(0.5);
+            })
+            .then(task.done.bind(task));
+      });
+
+      audit.define('cancel setTarget now', (task, should) => {
+        const context =
+            new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
+        const src = new ConstantSourceNode(context);
+        src.connect(context.destination);
+
+        src.offset.setValueAtTime(0.5, 0);
+        src.offset.setTargetAtTime(0, 0.5 * renderDuration, 0.1);
+        // Now cancel the effect of the setTarget.
+        src.offset.cancelAndHoldAtTime(0.5 * renderDuration);
+
+        src.start();
+        context.startRendering()
+            .then(buffer => {
+              let actual = buffer.getChannelData(0);
+              // Because the setTarget was cancelled, the output should be a
+              // constant.
+              should(
+                  actual,
+                  'After cancelling setTarget event starting now, output')
+                  .beConstantValueOf(0.5);
+            })
+            .then(task.done.bind(task));
+      });
+
+      audit.define('cancel future setValueCurve', (task, should) => {
+        const context =
+            new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
+        const src = new ConstantSourceNode(context);
+        src.connect(context.destination);
+
+        src.offset.setValueAtTime(0.5, 0);
+        src.offset.setValueCurveAtTime([-1, 1], 0.75 * renderDuration, 0.1);
+        // Now cancel the effect of the setTarget.
+        src.offset.cancelAndHoldAtTime(0.5 * renderDuration);
+
+        src.start();
+        context.startRendering()
+            .then(buffer => {
+              let actual = buffer.getChannelData(0);
+              // Because the setTarget was cancelled, the output should be a
+              // constant.
+              should(
+                  actual, 'After cancelling future setValueCurve event, output')
+                  .beConstantValueOf(0.5);
+            })
+            .then(task.done.bind(task));
+      });
+
+      audit.define('cancel setValueCurve now', (task, should) => {
+        const context =
+            new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
+        const src = new ConstantSourceNode(context);
+        src.connect(context.destination);
+
+        src.offset.setValueAtTime(0.5, 0);
+        src.offset.setValueCurveAtTime([-1, 1], 0.5 * renderDuration, 0.1);
+        // Now cancel the effect of the setTarget.
+        src.offset.cancelAndHoldAtTime(0.5 * renderDuration);
+
+        src.start();
+        context.startRendering()
+            .then(buffer => {
+              let actual = buffer.getChannelData(0);
+              // Because the setTarget was cancelled, the output should be a
+              // constant.
+              should(
+                  actual,
+                  'After cancelling current setValueCurve event starting now, output')
+                  .beConstantValueOf(0.5);
+            })
+            .then(task.done.bind(task));
+      });
+
+      audit.define(
+        {
+          label: 'linear, cancel, linear, cancel, linear',
+          description: 'Schedules 3 linear ramps, cancelling 2 of them, '
+            + 'so that we end up with 2 cancel events next to each other'
+        },
+        (task, should) => {
+          cancelTest2(
+            should,
+            linearRampTest('1st linearRamp'),
+            {valueThreshold: 0, curveThreshold: 5.9605e-8},
+            (g, cancelTime, expectedConstant, cancelTime2) => {
+              // Ramp from first cancel time to the end will be cancelled at
+              // second cancel time.
+              const v1 = expectedConstant;
+              const t1 = cancelTime;
+              const v2 = 2;
+              const t2 = renderDuration;
+              g[0].gain.linearRampToValueAtTime(v2, t2);
+              g[2].gain.setValueAtTime(v1, t1);
+              g[2].gain.linearRampToValueAtTime(v2, t2);
+
+              const expectedConstant2 =
+                audioParamLinearRamp(cancelTime2, v1, t1, v2, t2);
+
+              return {
+                constantEndTime: cancelTime,
+                message: `2nd linearRamp(${v2}, ${t2})`,
+                expectedConstant2
+              };
+            },
+            (g, cancelTime2, expectedConstant2) => {
+              // Ramp from second cancel time to the end.
+              const v3 = 0;
+              const t3 = renderDuration;
+              g[0].gain.linearRampToValueAtTime(v3, t3);
+              g[3].gain.setValueAtTime(expectedConstant2, cancelTime2);
+              g[3].gain.linearRampToValueAtTime(v3, t3);
+              return {
+                constantEndTime2: cancelTime2,
+                message2: `3rd linearRamp(${v3}, ${t3})`,
+              };
+            })
+            .then(() => task.done());
+        });
+
+      audit.run();
+
+      // Common function for doing a linearRamp test.  This just does a linear
+      // ramp from 0 to v0 at from time 0 to t0.  Then another linear ramp is
+      // scheduled from v0 to 0 from time t0 to t1.  This is the ramp that is to
+      // be cancelled.
+      function linearRampTest(message) {
+        return function(g, v0, t0, cancelTime) {
+          g[0].gain.setValueAtTime(0, 0);
+          g[1].gain.setValueAtTime(0, 0);
+          g[0].gain.linearRampToValueAtTime(v0, t0);
+          g[1].gain.linearRampToValueAtTime(v0, t0);
+
+          let v1 = 0;
+          let t1 = renderDuration;
+          g[0].gain.linearRampToValueAtTime(v1, t1);
+          g[1].gain.linearRampToValueAtTime(v1, t1);
+
+          expectedConstant =
+              Math.fround(v0 + (v1 - v0) * (cancelTime - t0) / (t1 - t0));
+
+          return {
+            expectedConstant: expectedConstant,
+            autoMessage:
+                message + ': linearRampToValue(' + v1 + ', ' + t1 + ')',
+            summary: message,
+          };
+        }
+      }
+
+      // Run the cancellation test. A set of automations is created and
+      // canceled.
+      //
+      // |testerFunction| is a function that generates the automation to be
+      // tested.  It is given an array of 3 gain nodes, the value and time of an
+      // initial linear ramp, and the time where the cancellation should occur.
+      // The function must do the automations for the first two gain nodes.  It
+      // must return a dictionary with |expectedConstant| being the value at the
+      // cancellation time, |autoMessage| for message to describe the test, and
+      // |summary| for general summary message to be printed at the end of the
+      // test.
+      //
+      // |thresholdOptions| is a property bag that specifies the error threshold
+      // to use. |thresholdOptions.valueThreshold| is the error threshold for
+      // comparing the actual constant output after cancelling to the expected
+      // value.  |thresholdOptions.curveThreshold| is the error threshold for
+      // comparing the actual and expected automation curves before the
+      // cancelation point.
+      //
+      // For cancellation tests, |postCancelTest| is a function that schedules
+      // some automation after the cancellation.  It takes 3 arguments: an array
+      // of the gain nodes, the cancellation time, and the expected value at the
+      // cancellation time.  This function must return a dictionary consisting
+      // of |constantEndtime| indicating when the held constant from
+      // cancellation stops being constant, |message| giving a summary of what
+      // automation is being used, and |errorThreshold| that is the error
+      // threshold between the expected curve and the actual curve.
+      //
+      function cancelTest(
+          should, testerFunction, thresholdOptions, postCancelTest) {
+        // Create a context with three channels.  Channel 0 is the test channel
+        // containing the actual output that includes the cancellation of
+        // events.  Channel 1 is the expected data upto the cancellation so we
+        // can verify the cancellation produced the correct result.  Channel 2
+        // is for verifying events inserted after the cancellation so we can
+        // verify that automations are correctly generated after the
+        // cancellation point.
+        let context =
+            new OfflineAudioContext(3, renderDuration * sampleRate, sampleRate);
+
+        // Test source is a constant signal
+        let src = context.createBufferSource();
+        src.buffer = createConstantBuffer(context, 1, 1);
+        src.loop = true;
+
+        // We'll do the automation tests with three gain nodes.  One (g0) will
+        // have cancelAndHoldAtTime and the other (g1) will not.  g1 is
+        // used as the expected result for that automation up to the
+        // cancellation point.  They should be the same.  The third node (g2) is
+        // used for testing automations inserted after the cancellation point,
+        // if any.  g2 is the expected result from the cancellation point to the
+        // end of the test.
+
+        let g0 = context.createGain();
+        let g1 = context.createGain();
+        let g2 = context.createGain();
+        let v0 = 1;
+        let t0 = 0.01;
+
+        let cancelTime = renderDuration / 2;
+
+        // Test automation here.  The tester function is responsible for setting
+        // up the gain nodes with the desired automation for testing.
+        autoResult = testerFunction([g0, g1, g2], v0, t0, cancelTime);
+        let expectedConstant = autoResult.expectedConstant;
+        let autoMessage = autoResult.autoMessage;
+        let summaryMessage = autoResult.summary;
+
+        // Cancel scheduled events somewhere in the middle of the test
+        // automation.
+        g0.gain.cancelAndHoldAtTime(cancelTime);
+
+        let constantEndTime;
+        if (postCancelTest) {
+          postResult =
+              postCancelTest([g0, g1, g2], cancelTime, expectedConstant);
+          constantEndTime = postResult.constantEndTime;
+        }
+
+        // Connect everything together (with a merger to make a two-channel
+        // result).  Channel 0 is the test (with cancelAndHoldAtTime) and
+        // channel 1 is the reference (without cancelAndHoldAtTime).
+        // Channel 1 is used to verify that everything up to the cancellation
+        // has the correct values.
+        src.connect(g0);
+        src.connect(g1);
+        src.connect(g2);
+        let merger = context.createChannelMerger(3);
+        g0.connect(merger, 0, 0);
+        g1.connect(merger, 0, 1);
+        g2.connect(merger, 0, 2);
+        merger.connect(context.destination);
+
+        // Go!
+        src.start();
+
+        return context.startRendering().then(function(buffer) {
+          let actual = buffer.getChannelData(0);
+          let expected = buffer.getChannelData(1);
+
+          // The actual output should be a constant from the cancel time to the
+          // end.  We use the last value of the actual output as the constant,
+          // but we also want to compare that with what we thought it should
+          // really be.
+
+          let cancelFrame = Math.ceil(cancelTime * sampleRate);
+
+          // Verify that the curves up to the cancel time are "identical".  The
+          // should be but round-off may make them differ slightly due to the
+          // way cancelling is done.
+          let endFrame = Math.floor(cancelTime * sampleRate);
+          should(
+              actual.slice(0, endFrame),
+              autoMessage + ' up to time ' + cancelTime)
+              .beCloseToArray(
+                  expected.slice(0, endFrame),
+                  {absoluteThreshold: thresholdOptions.curveThreshold});
+
+          // Verify the output after the cancellation is a constant.
+          let actualTail;
+          let constantEndFrame;
+
+          if (postCancelTest) {
+            constantEndFrame = Math.ceil(constantEndTime * sampleRate);
+            actualTail = actual.slice(cancelFrame, constantEndFrame);
+          } else {
+            actualTail = actual.slice(cancelFrame);
+          }
+
+          let actualConstant = actual[cancelFrame];
+
+          should(
+              actualTail,
+              'Cancelling ' + autoMessage + ' at time ' + cancelTime)
+              .beConstantValueOf(actualConstant);
+
+          // Verify that the constant is the value we expect.
+          should(
+              actualConstant,
+              'Expected value for cancelling ' + autoMessage + ' at time ' +
+                  cancelTime)
+              .beCloseTo(
+                  expectedConstant,
+                  {threshold: thresholdOptions.valueThreshold});
+
+          // Verify the curve after the constantEndTime matches our
+          // expectations.
+          if (postCancelTest) {
+            let c2 = buffer.getChannelData(2);
+            should(actual.slice(constantEndFrame), postResult.message)
+                .beCloseToArray(
+                    c2.slice(constantEndFrame),
+                    {absoluteThreshold: postResult.errorThreshold || 0});
+          }
+        });
+      }
+
+      // Similar to cancelTest, but does 2 cancels.
+      function cancelTest2(
+          should, testerFunction, thresholdOptions,
+          postCancelTest, postCancelTest2) {
+        // Channel 0: Actual output that includes the cancellation of events.
+        // Channel 1: Expected data up to the first cancellation.
+        // Channel 2: Expected data from 1st cancellation to 2nd cancellation.
+        // Channel 3: Expected data from 2nd cancellation to the end.
+        const context =
+          new OfflineAudioContext(4, renderDuration * sampleRate, sampleRate);
+
+        const src = context.createConstantSource();
+
+        // g0: Actual gain which will have cancelAndHoldAtTime called on it
+        // twice.
+        // g1: Expected gain from start to the 1st cancel.
+        // g2: Expected gain from 1st cancel to the 2nd cancel.
+        // g3: Expected gain from the 2nd cancel to the end.
+        const g0 = context.createGain();
+        const g1 = context.createGain();
+        const g2 = context.createGain();
+        const g3 = context.createGain();
+        const v0 = 1;
+        const t0 = 0.01;
+
+        const cancelTime1 = renderDuration * 0.5;
+        const cancelTime2 = renderDuration * 0.75;
+
+        // Run testerFunction to generate the 1st ramp.
+        const {
+          expectedConstant, autoMessage, summaryMessage} =
+            testerFunction([g0, g1, g2], v0, t0, cancelTime1);
+
+        // 1st cancel, cancelling the 1st ramp.
+        g0.gain.cancelAndHoldAtTime(cancelTime1);
+
+        // Run postCancelTest to generate the 2nd ramp.
+        const {
+          constantEndTime, message, errorThreshold = 0, expectedConstant2} =
+            postCancelTest(
+              [g0, g1, g2], cancelTime1, expectedConstant, cancelTime2);
+
+        // 2nd cancel, cancelling the 2nd ramp.
+        g0.gain.cancelAndHoldAtTime(cancelTime2);
+
+        // Run postCancelTest2 to generate the 3rd ramp.
+        const {constantEndTime2, message2} =
+          postCancelTest2([g0, g1, g2, g3], cancelTime2, expectedConstant2);
+
+        // Connect everything together
+        src.connect(g0);
+        src.connect(g1);
+        src.connect(g2);
+        src.connect(g3);
+        const merger = context.createChannelMerger(4);
+        g0.connect(merger, 0, 0);
+        g1.connect(merger, 0, 1);
+        g2.connect(merger, 0, 2);
+        g3.connect(merger, 0, 3);
+        merger.connect(context.destination);
+
+        // Go!
+        src.start();
+
+        return context.startRendering().then(function (buffer) {
+          const actual = buffer.getChannelData(0);
+          const expected1 = buffer.getChannelData(1);
+          const expected2 = buffer.getChannelData(2);
+          const expected3 = buffer.getChannelData(3);
+
+          const cancelFrame1 = Math.ceil(cancelTime1 * sampleRate);
+          const cancelFrame2 = Math.ceil(cancelTime2 * sampleRate);
+
+          const constantEndFrame1 = Math.ceil(constantEndTime * sampleRate);
+          const constantEndFrame2 = Math.ceil(constantEndTime2 * sampleRate);
+
+          const actualTail1 = actual.slice(cancelFrame1, constantEndFrame1);
+          const actualTail2 = actual.slice(cancelFrame2, constantEndFrame2);
+
+          const actualConstant1 = actual[cancelFrame1];
+          const actualConstant2 = actual[cancelFrame2];
+
+          // Verify first section curve
+          should(
+            actual.slice(0, cancelFrame1),
+            autoMessage + ' up to time ' + cancelTime1)
+            .beCloseToArray(
+              expected1.slice(0, cancelFrame1),
+              {absoluteThreshold: thresholdOptions.curveThreshold});
+
+          // Verify that a value was held after 1st cancel
+          should(
+            actualTail1,
+            'Cancelling ' + autoMessage + ' at time ' + cancelTime1)
+            .beConstantValueOf(actualConstant1);
+
+          // Verify that held value after 1st cancel was correct
+          should(
+            actualConstant1,
+            'Expected value for cancelling ' + autoMessage + ' at time ' +
+            cancelTime1)
+            .beCloseTo(
+              expectedConstant,
+              {threshold: thresholdOptions.valueThreshold});
+
+          // Verify middle section curve
+          should(actual.slice(constantEndFrame1, cancelFrame2), message)
+            .beCloseToArray(
+              expected2.slice(constantEndFrame1, cancelFrame2),
+              {absoluteThreshold: errorThreshold});
+
+          // Verify that a value was held after 2nd cancel
+          should(
+            actualTail2,
+            'Cancelling ' + message + ' at time ' + cancelTime2)
+            .beConstantValueOf(actualConstant2);
+
+          // Verify that held value after 2nd cancel was correct
+          should(
+            actualConstant2,
+            'Expected value for cancelling ' + message + ' at time ' +
+            cancelTime2)
+            .beCloseTo(
+              expectedConstant2,
+              {threshold: thresholdOptions.valueThreshold});
+
+          // Verify end section curve
+          should(actual.slice(constantEndFrame2), message2)
+            .beCloseToArray(
+              expected3.slice(constantEndFrame2),
+              {absoluteThreshold: errorThreshold || 0});
+        });
+      }
+    </script>
+  </body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamnominalrangeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range-expected.txt (0 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range-expected.txt                          (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range-expected.txt     2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -0,0 +1,329 @@
</span><ins>+
+PASS # AUDIT TASK RUNNER STARTED.
+PASS Executing "initialize"
+PASS Executing "Offline createGain"
+PASS Executing "Offline createDelay"
+PASS Executing "Offline createBufferSource"
+PASS Executing "Offline createStereoPanner"
+PASS Executing "Offline createDynamicsCompressor"
+PASS Executing "Offline createBiquadFilter"
+PASS Executing "Offline createOscillator"
+PASS Executing "Offline createPanner"
+PASS Executing "Offline createConstantSource"
+PASS Executing "Offline createBuffer"
+PASS Executing "Offline createIIRFilter"
+PASS Executing "Offline createWaveShaper"
+PASS Executing "Offline createConvolver"
+PASS Executing "Offline createAnalyser"
+PASS Executing "Offline createScriptProcessor"
+PASS Executing "Offline createPeriodicWave"
+PASS Executing "Offline createChannelSplitter"
+PASS Executing "Offline createChannelMerger"
+PASS Executing "Online createMediaElementSource"
+PASS Executing "Online createMediaStreamDestination"
+PASS Executing "AudioListener"
+PASS Executing "verifyTests"
+PASS Executing "automation"
+PASS Audit report
+PASS > [initialize]
+PASS   Create offline context for tests did not throw an exception.
+PASS   Create online context for tests did not throw an exception.
+PASS < [initialize] All assertions passed. (total 2 assertions)
+PASS > [Offline createGain]
+PASS   GainNode.gain.minValue is equal to -3.402823e+38.
+PASS   GainNode.gain.maxValue is equal to 3.402823e+38.
+PASS   GainNode.gain.minValue = 42 is not equal to 42.
+PASS   GainNode.gain.minValue is read-only is equal to true.
+PASS   GainNode.gain.maxValue = 42 is not equal to 42.
+PASS   GainNode.gain.maxValue is read-only is equal to true.
+PASS   Nominal ranges for AudioParam(s) of GainNode are correct
+PASS < [Offline createGain] All assertions passed. (total 7 assertions)
+PASS > [Offline createDelay]
+PASS   DelayNode.delayTime.minValue is equal to 0.
+PASS   DelayNode.delayTime.maxValue is equal to 1.5.
+PASS   DelayNode.delayTime.minValue = 42 is not equal to 42.
+PASS   DelayNode.delayTime.minValue is read-only is equal to true.
+PASS   DelayNode.delayTime.maxValue = 42 is not equal to 42.
+PASS   DelayNode.delayTime.maxValue is read-only is equal to true.
+PASS   Set DelayNode.delayTime.value = -1 is equal to 0.
+PASS   Set DelayNode.delayTime.value = 4 is equal to 1.5.
+PASS   DelayNode.delayTime was clipped to lie within the nominal range is equal to true.
+PASS   Nominal ranges for AudioParam(s) of DelayNode are correct
+PASS < [Offline createDelay] All assertions passed. (total 10 assertions)
+PASS > [Offline createBufferSource]
+PASS   AudioBufferSourceNode.playbackRate.minValue is equal to -3.402823e+38.
+PASS   AudioBufferSourceNode.playbackRate.maxValue is equal to 3.402823e+38.
+PASS   AudioBufferSourceNode.playbackRate.minValue = 42 is not equal to 42.
+PASS   AudioBufferSourceNode.playbackRate.minValue is read-only is equal to true.
+PASS   AudioBufferSourceNode.playbackRate.maxValue = 42 is not equal to 42.
+PASS   AudioBufferSourceNode.playbackRate.maxValue is read-only is equal to true.
+PASS   AudioBufferSourceNode.detune.minValue is equal to -3.402823e+38.
+PASS   AudioBufferSourceNode.detune.maxValue is equal to 3.402823e+38.
+PASS   AudioBufferSourceNode.detune.minValue = 42 is not equal to 42.
+PASS   AudioBufferSourceNode.detune.minValue is read-only is equal to true.
+PASS   AudioBufferSourceNode.detune.maxValue = 42 is not equal to 42.
+PASS   AudioBufferSourceNode.detune.maxValue is read-only is equal to true.
+PASS   Nominal ranges for AudioParam(s) of AudioBufferSourceNode are correct
+PASS < [Offline createBufferSource] All assertions passed. (total 13 assertions)
+PASS > [Offline createStereoPanner]
+PASS   StereoPannerNode.pan.minValue is equal to -1.
+PASS   StereoPannerNode.pan.maxValue is equal to 1.
+PASS   StereoPannerNode.pan.minValue = 42 is not equal to 42.
+PASS   StereoPannerNode.pan.minValue is read-only is equal to true.
+PASS   StereoPannerNode.pan.maxValue = 42 is not equal to 42.
+PASS   StereoPannerNode.pan.maxValue is read-only is equal to true.
+PASS   Set StereoPannerNode.pan.value = -3 is equal to -1.
+PASS   Set StereoPannerNode.pan.value = 3 is equal to 1.
+PASS   StereoPannerNode.pan was clipped to lie within the nominal range is equal to true.
+PASS   Nominal ranges for AudioParam(s) of StereoPannerNode are correct
+PASS < [Offline createStereoPanner] All assertions passed. (total 10 assertions)
+PASS > [Offline createDynamicsCompressor]
+PASS   DynamicsCompressorNode.threshold.minValue is equal to -100.
+PASS   DynamicsCompressorNode.threshold.maxValue is equal to 0.
+PASS   DynamicsCompressorNode.threshold.minValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.threshold.minValue is read-only is equal to true.
+PASS   DynamicsCompressorNode.threshold.maxValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.threshold.maxValue is read-only is equal to true.
+PASS   Set DynamicsCompressorNode.threshold.value = -201 is equal to -100.
+PASS   Set DynamicsCompressorNode.threshold.value = 1 is equal to 0.
+PASS   DynamicsCompressorNode.threshold was clipped to lie within the nominal range is equal to true.
+PASS   DynamicsCompressorNode.knee.minValue is equal to 0.
+PASS   DynamicsCompressorNode.knee.maxValue is equal to 40.
+PASS   DynamicsCompressorNode.knee.minValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.knee.minValue is read-only is equal to true.
+PASS   DynamicsCompressorNode.knee.maxValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.knee.maxValue is read-only is equal to true.
+PASS   Set DynamicsCompressorNode.knee.value = -1 is equal to 0.
+PASS   Set DynamicsCompressorNode.knee.value = 81 is equal to 40.
+PASS   DynamicsCompressorNode.knee was clipped to lie within the nominal range is equal to true.
+PASS   DynamicsCompressorNode.ratio.minValue is equal to 1.
+PASS   DynamicsCompressorNode.ratio.maxValue is equal to 20.
+PASS   DynamicsCompressorNode.ratio.minValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.ratio.minValue is read-only is equal to true.
+PASS   DynamicsCompressorNode.ratio.maxValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.ratio.maxValue is read-only is equal to true.
+PASS   Set DynamicsCompressorNode.ratio.value = 1 is equal to 1.
+PASS   Set DynamicsCompressorNode.ratio.value = 41 is equal to 20.
+PASS   DynamicsCompressorNode.ratio was clipped to lie within the nominal range is equal to true.
+PASS   DynamicsCompressorNode.attack.minValue is equal to 0.
+PASS   DynamicsCompressorNode.attack.maxValue is equal to 1.
+PASS   DynamicsCompressorNode.attack.minValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.attack.minValue is read-only is equal to true.
+PASS   DynamicsCompressorNode.attack.maxValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.attack.maxValue is read-only is equal to true.
+PASS   Set DynamicsCompressorNode.attack.value = -1 is equal to 0.
+PASS   Set DynamicsCompressorNode.attack.value = 3 is equal to 1.
+PASS   DynamicsCompressorNode.attack was clipped to lie within the nominal range is equal to true.
+PASS   DynamicsCompressorNode.release.minValue is equal to 0.
+PASS   DynamicsCompressorNode.release.maxValue is equal to 1.
+PASS   DynamicsCompressorNode.release.minValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.release.minValue is read-only is equal to true.
+PASS   DynamicsCompressorNode.release.maxValue = 42 is not equal to 42.
+PASS   DynamicsCompressorNode.release.maxValue is read-only is equal to true.
+PASS   Set DynamicsCompressorNode.release.value = -1 is equal to 0.
+PASS   Set DynamicsCompressorNode.release.value = 3 is equal to 1.
+PASS   DynamicsCompressorNode.release was clipped to lie within the nominal range is equal to true.
+PASS   Nominal ranges for AudioParam(s) of DynamicsCompressorNode are correct
+PASS < [Offline createDynamicsCompressor] All assertions passed. (total 46 assertions)
+PASS > [Offline createBiquadFilter]
+PASS   BiquadFilterNode.frequency.minValue is equal to 0.
+PASS   BiquadFilterNode.frequency.maxValue is equal to 24000.
+PASS   BiquadFilterNode.frequency.minValue = 42 is not equal to 42.
+PASS   BiquadFilterNode.frequency.minValue is read-only is equal to true.
+PASS   BiquadFilterNode.frequency.maxValue = 42 is not equal to 42.
+PASS   BiquadFilterNode.frequency.maxValue is read-only is equal to true.
+PASS   Set BiquadFilterNode.frequency.value = -1 is equal to 0.
+PASS   Set BiquadFilterNode.frequency.value = 48001 is equal to 24000.
+PASS   BiquadFilterNode.frequency was clipped to lie within the nominal range is equal to true.
+PASS   BiquadFilterNode.detune.minValue is equal to -153600.
+PASS   BiquadFilterNode.detune.maxValue is equal to 153600.
+PASS   BiquadFilterNode.detune.minValue = 42 is not equal to 42.
+PASS   BiquadFilterNode.detune.minValue is read-only is equal to true.
+PASS   BiquadFilterNode.detune.maxValue = 42 is not equal to 42.
+PASS   BiquadFilterNode.detune.maxValue is read-only is equal to true.
+PASS   Set BiquadFilterNode.detune.value = -307201 is equal to -153600.
+PASS   Set BiquadFilterNode.detune.value = 307201 is equal to 153600.
+PASS   BiquadFilterNode.detune was clipped to lie within the nominal range is equal to true.
+PASS   BiquadFilterNode.Q.minValue is equal to -3.402823e+38.
+PASS   BiquadFilterNode.Q.maxValue is equal to 3.402823e+38.
+PASS   BiquadFilterNode.Q.minValue = 42 is not equal to 42.
+PASS   BiquadFilterNode.Q.minValue is read-only is equal to true.
+PASS   BiquadFilterNode.Q.maxValue = 42 is not equal to 42.
+PASS   BiquadFilterNode.Q.maxValue is read-only is equal to true.
+PASS   BiquadFilterNode.gain.minValue is equal to -3.402823e+38.
+PASS   BiquadFilterNode.gain.maxValue is equal to 1541.273682.
+PASS   BiquadFilterNode.gain.minValue = 42 is not equal to 42.
+PASS   BiquadFilterNode.gain.minValue is read-only is equal to true.
+PASS   BiquadFilterNode.gain.maxValue = 42 is not equal to 42.
+PASS   BiquadFilterNode.gain.maxValue is read-only is equal to true.
+PASS   Set BiquadFilterNode.gain.value = 3083.547363 is equal to 1541.273682.
+PASS   BiquadFilterNode.gain was clipped to lie within the nominal range is equal to true.
+PASS   Nominal ranges for AudioParam(s) of BiquadFilterNode are correct
+PASS < [Offline createBiquadFilter] All assertions passed. (total 33 assertions)
+PASS > [Offline createOscillator]
+PASS   OscillatorNode.frequency.minValue is equal to -24000.
+PASS   OscillatorNode.frequency.maxValue is equal to 24000.
+PASS   OscillatorNode.frequency.minValue = 42 is not equal to 42.
+PASS   OscillatorNode.frequency.minValue is read-only is equal to true.
+PASS   OscillatorNode.frequency.maxValue = 42 is not equal to 42.
+PASS   OscillatorNode.frequency.maxValue is read-only is equal to true.
+PASS   Set OscillatorNode.frequency.value = -48001 is equal to -24000.
+PASS   Set OscillatorNode.frequency.value = 48001 is equal to 24000.
+PASS   OscillatorNode.frequency was clipped to lie within the nominal range is equal to true.
+PASS   OscillatorNode.detune.minValue is equal to -153600.
+PASS   OscillatorNode.detune.maxValue is equal to 153600.
+PASS   OscillatorNode.detune.minValue = 42 is not equal to 42.
+PASS   OscillatorNode.detune.minValue is read-only is equal to true.
+PASS   OscillatorNode.detune.maxValue = 42 is not equal to 42.
+PASS   OscillatorNode.detune.maxValue is read-only is equal to true.
+PASS   Set OscillatorNode.detune.value = -307201 is equal to -153600.
+PASS   Set OscillatorNode.detune.value = 307201 is equal to 153600.
+PASS   OscillatorNode.detune was clipped to lie within the nominal range is equal to true.
+PASS   Nominal ranges for AudioParam(s) of OscillatorNode are correct
+PASS < [Offline createOscillator] All assertions passed. (total 19 assertions)
+PASS > [Offline createPanner]
+PASS   PannerNode.positionX.minValue is equal to -3.402823e+38.
+PASS   PannerNode.positionX.maxValue is equal to 3.402823e+38.
+PASS   PannerNode.positionX.minValue = 42 is not equal to 42.
+PASS   PannerNode.positionX.minValue is read-only is equal to true.
+PASS   PannerNode.positionX.maxValue = 42 is not equal to 42.
+PASS   PannerNode.positionX.maxValue is read-only is equal to true.
+PASS   PannerNode.positionY.minValue is equal to -3.402823e+38.
+PASS   PannerNode.positionY.maxValue is equal to 3.402823e+38.
+PASS   PannerNode.positionY.minValue = 42 is not equal to 42.
+PASS   PannerNode.positionY.minValue is read-only is equal to true.
+PASS   PannerNode.positionY.maxValue = 42 is not equal to 42.
+PASS   PannerNode.positionY.maxValue is read-only is equal to true.
+PASS   PannerNode.positionZ.minValue is equal to -3.402823e+38.
+PASS   PannerNode.positionZ.maxValue is equal to 3.402823e+38.
+PASS   PannerNode.positionZ.minValue = 42 is not equal to 42.
+PASS   PannerNode.positionZ.minValue is read-only is equal to true.
+PASS   PannerNode.positionZ.maxValue = 42 is not equal to 42.
+PASS   PannerNode.positionZ.maxValue is read-only is equal to true.
+PASS   PannerNode.orientationX.minValue is equal to -3.402823e+38.
+PASS   PannerNode.orientationX.maxValue is equal to 3.402823e+38.
+PASS   PannerNode.orientationX.minValue = 42 is not equal to 42.
+PASS   PannerNode.orientationX.minValue is read-only is equal to true.
+PASS   PannerNode.orientationX.maxValue = 42 is not equal to 42.
+PASS   PannerNode.orientationX.maxValue is read-only is equal to true.
+PASS   PannerNode.orientationY.minValue is equal to -3.402823e+38.
+PASS   PannerNode.orientationY.maxValue is equal to 3.402823e+38.
+PASS   PannerNode.orientationY.minValue = 42 is not equal to 42.
+PASS   PannerNode.orientationY.minValue is read-only is equal to true.
+PASS   PannerNode.orientationY.maxValue = 42 is not equal to 42.
+PASS   PannerNode.orientationY.maxValue is read-only is equal to true.
+PASS   PannerNode.orientationZ.minValue is equal to -3.402823e+38.
+PASS   PannerNode.orientationZ.maxValue is equal to 3.402823e+38.
+PASS   PannerNode.orientationZ.minValue = 42 is not equal to 42.
+PASS   PannerNode.orientationZ.minValue is read-only is equal to true.
+PASS   PannerNode.orientationZ.maxValue = 42 is not equal to 42.
+PASS   PannerNode.orientationZ.maxValue is read-only is equal to true.
+PASS   Nominal ranges for AudioParam(s) of PannerNode are correct
+PASS < [Offline createPanner] All assertions passed. (total 37 assertions)
+PASS > [Offline createConstantSource]
+PASS   ConstantSourceNode.offset.minValue is equal to -3.402823e+38.
+PASS   ConstantSourceNode.offset.maxValue is equal to 3.402823e+38.
+PASS   ConstantSourceNode.offset.minValue = 42 is not equal to 42.
+PASS   ConstantSourceNode.offset.minValue is read-only is equal to true.
+PASS   ConstantSourceNode.offset.maxValue = 42 is not equal to 42.
+PASS   ConstantSourceNode.offset.maxValue is read-only is equal to true.
+PASS   Nominal ranges for AudioParam(s) of ConstantSourceNode are correct
+PASS < [Offline createConstantSource] All assertions passed. (total 7 assertions)
+PASS > [Offline createBuffer]
+PASS   AudioBuffer has no AudioParams as expected
+PASS < [Offline createBuffer] All assertions passed. (total 1 assertions)
+PASS > [Offline createIIRFilter]
+PASS   IIRFilterNode has no AudioParams as expected
+PASS < [Offline createIIRFilter] All assertions passed. (total 1 assertions)
+PASS > [Offline createWaveShaper]
+PASS   WaveShaperNode has no AudioParams as expected
+PASS < [Offline createWaveShaper] All assertions passed. (total 1 assertions)
+PASS > [Offline createConvolver]
+PASS   ConvolverNode has no AudioParams as expected
+PASS < [Offline createConvolver] All assertions passed. (total 1 assertions)
+PASS > [Offline createAnalyser]
+PASS   AnalyserNode has no AudioParams as expected
+PASS < [Offline createAnalyser] All assertions passed. (total 1 assertions)
+PASS > [Offline createScriptProcessor]
+PASS   ScriptProcessorNode has no AudioParams as expected
+PASS < [Offline createScriptProcessor] All assertions passed. (total 1 assertions)
+PASS > [Offline createPeriodicWave]
+PASS   PeriodicWave has no AudioParams as expected
+PASS < [Offline createPeriodicWave] All assertions passed. (total 1 assertions)
+PASS > [Offline createChannelSplitter]
+PASS   ChannelSplitterNode has no AudioParams as expected
+PASS < [Offline createChannelSplitter] All assertions passed. (total 1 assertions)
+PASS > [Offline createChannelMerger]
+PASS   ChannelMergerNode has no AudioParams as expected
+PASS < [Offline createChannelMerger] All assertions passed. (total 1 assertions)
+PASS > [Online createMediaElementSource]
+PASS   MediaElementAudioSourceNode has no AudioParams as expected
+PASS < [Online createMediaElementSource] All assertions passed. (total 1 assertions)
+PASS > [Online createMediaStreamDestination]
+PASS   MediaStreamAudioDestinationNode has no AudioParams as expected
+PASS < [Online createMediaStreamDestination] All assertions passed. (total 1 assertions)
+PASS > [AudioListener]
+PASS   AudioListener.positionX.minValue is equal to -3.402823e+38.
+PASS   AudioListener.positionX.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.positionX.minValue = 42 is not equal to 42.
+PASS   AudioListener.positionX.minValue is read-only is equal to true.
+PASS   AudioListener.positionX.maxValue = 42 is not equal to 42.
+PASS   AudioListener.positionX.maxValue is read-only is equal to true.
+PASS   AudioListener.positionY.minValue is equal to -3.402823e+38.
+PASS   AudioListener.positionY.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.positionY.minValue = 42 is not equal to 42.
+PASS   AudioListener.positionY.minValue is read-only is equal to true.
+PASS   AudioListener.positionY.maxValue = 42 is not equal to 42.
+PASS   AudioListener.positionY.maxValue is read-only is equal to true.
+PASS   AudioListener.positionZ.minValue is equal to -3.402823e+38.
+PASS   AudioListener.positionZ.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.positionZ.minValue = 42 is not equal to 42.
+PASS   AudioListener.positionZ.minValue is read-only is equal to true.
+PASS   AudioListener.positionZ.maxValue = 42 is not equal to 42.
+PASS   AudioListener.positionZ.maxValue is read-only is equal to true.
+PASS   AudioListener.forwardX.minValue is equal to -3.402823e+38.
+PASS   AudioListener.forwardX.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.forwardX.minValue = 42 is not equal to 42.
+PASS   AudioListener.forwardX.minValue is read-only is equal to true.
+PASS   AudioListener.forwardX.maxValue = 42 is not equal to 42.
+PASS   AudioListener.forwardX.maxValue is read-only is equal to true.
+PASS   AudioListener.forwardY.minValue is equal to -3.402823e+38.
+PASS   AudioListener.forwardY.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.forwardY.minValue = 42 is not equal to 42.
+PASS   AudioListener.forwardY.minValue is read-only is equal to true.
+PASS   AudioListener.forwardY.maxValue = 42 is not equal to 42.
+PASS   AudioListener.forwardY.maxValue is read-only is equal to true.
+PASS   AudioListener.forwardZ.minValue is equal to -3.402823e+38.
+PASS   AudioListener.forwardZ.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.forwardZ.minValue = 42 is not equal to 42.
+PASS   AudioListener.forwardZ.minValue is read-only is equal to true.
+PASS   AudioListener.forwardZ.maxValue = 42 is not equal to 42.
+PASS   AudioListener.forwardZ.maxValue is read-only is equal to true.
+PASS   AudioListener.upX.minValue is equal to -3.402823e+38.
+PASS   AudioListener.upX.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.upX.minValue = 42 is not equal to 42.
+PASS   AudioListener.upX.minValue is read-only is equal to true.
+PASS   AudioListener.upX.maxValue = 42 is not equal to 42.
+PASS   AudioListener.upX.maxValue is read-only is equal to true.
+PASS   AudioListener.upY.minValue is equal to -3.402823e+38.
+PASS   AudioListener.upY.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.upY.minValue = 42 is not equal to 42.
+PASS   AudioListener.upY.minValue is read-only is equal to true.
+PASS   AudioListener.upY.maxValue = 42 is not equal to 42.
+PASS   AudioListener.upY.maxValue is read-only is equal to true.
+PASS   AudioListener.upZ.minValue is equal to -3.402823e+38.
+PASS   AudioListener.upZ.maxValue is equal to 3.402823e+38.
+PASS   AudioListener.upZ.minValue = 42 is not equal to 42.
+PASS   AudioListener.upZ.minValue is read-only is equal to true.
+PASS   AudioListener.upZ.maxValue = 42 is not equal to 42.
+PASS   AudioListener.upZ.maxValue is read-only is equal to true.
+PASS   Nominal ranges for AudioParam(s) of AudioListener are correct
+PASS < [AudioListener] All assertions passed. (total 55 assertions)
+PASS > [verifyTests]
+PASS   Number of nodes not tested : 0
+PASS < [verifyTests] All assertions passed. (total 1 assertions)
+PASS > [automation]
+PASS   Test automations (check console logs) did not throw an exception.
+PASS < [automation] All assertions passed. (total 1 assertions)
+PASS # AUDIT TASK RUNNER FINISHED: 24 tasks ran successfully.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamnominalrangehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range.html (0 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range.html                          (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range.html     2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -0,0 +1,497 @@
</span><ins>+<!DOCTYPE html>
+<html>
+  <head>
+    <title>
+      Test AudioParam Nominal Range Values
+    </title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/resources/audit-util.js"></script>
+    <script src="/webaudio/resources/audit.js"></script>
+  </head>
+  <body>
+    <script id="layout-test-code">
+      // Some arbitrary sample rate for the offline context.
+      let sampleRate = 48000;
+
+      // The actual contexts to use.  Generally use the offline context for
+      // testing except for the media nodes which require an AudioContext.
+      let offlineContext;
+      let audioContext;
+
+      // The set of all methods that we've tested for verifying that we tested
+      // all of the necessary objects.
+      let testedMethods = new Set();
+
+      // The most positive single float value (the value just before infinity).
+      // Be careful when changing this value!  Javascript only uses double
+      // floats, so the value here should be the max single-float value,
+      // converted directly to a double-float value.  This also depends on
+      // Javascript reading this value and producing the desired double-float
+      // value correctly.
+      let mostPositiveFloat = 3.4028234663852886e38;
+
+      let audit = Audit.createTaskRunner();
+
+      // Array describing the tests that should be run.  |testOfflineConfigs| is
+      // for tests that can use an offline context. |testOnlineConfigs| is for
+      // tests that need to use an online context.  Offline contexts are
+      // preferred when possible.
+      let testOfflineConfigs = [
+        {
+          // The name of the method to create the particular node to be tested.
+          creator: 'createGain',
+
+          // Any args to pass to the creator function.
+          args: [],
+
+          // The min/max limits for each AudioParam of the node.  This is a
+          // dictionary whose keys are
+          // the names of each AudioParam in the node.  Don't define this if the
+          // node doesn't have any
+          // AudioParam attributes.
+          limits: {
+            gain: {
+              // The expected min and max values for this AudioParam.
+              minValue: -mostPositiveFloat,
+              maxValue: mostPositiveFloat
+            }
+          }
+        },
+        {
+          creator: 'createDelay',
+          // Just specify a non-default value for the maximum delay so we can
+          // make sure the limits are
+          // set correctly.
+          args: [1.5],
+          limits: {delayTime: {minValue: 0, maxValue: 1.5}}
+        },
+        {
+          creator: 'createBufferSource',
+          args: [],
+          limits: {
+            playbackRate:
+                {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat},
+            detune: {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat}
+          }
+        },
+        {
+          creator: 'createStereoPanner',
+          args: [],
+          limits: {pan: {minValue: -1, maxValue: 1}}
+        },
+        {
+          creator: 'createDynamicsCompressor',
+          args: [],
+          // Do not set limits for reduction;  it's currently an AudioParam but
+          // should be a float.
+          // So let the test fail for reduction.  When reduction is changed,
+          // this test will then
+          // correctly pass.
+          limits: {
+            threshold: {minValue: -100, maxValue: 0},
+            knee: {minValue: 0, maxValue: 40},
+            ratio: {minValue: 1, maxValue: 20},
+            attack: {minValue: 0, maxValue: 1},
+            release: {minValue: 0, maxValue: 1}
+          }
+        },
+        {
+          creator: 'createBiquadFilter',
+          args: [],
+          limits: {
+            gain: {
+              minValue: -mostPositiveFloat,
+              // This complicated expression is used to get all the arithmetic
+              // to round to the correct single-precision float value for the
+              // desired max.  This also assumes that the implication computes
+              // the limit as 40 * log10f(std::numeric_limits<float>::max()).
+              maxValue:
+                  Math.fround(40 * Math.fround(Math.log10(mostPositiveFloat)))
+            },
+            Q: {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat},
+            frequency: {minValue: 0, maxValue: sampleRate / 2},
+            detune: {
+              minValue: -Math.fround(1200 * Math.log2(mostPositiveFloat)),
+              maxValue: Math.fround(1200 * Math.log2(mostPositiveFloat))
+            }
+          }
+        },
+        {
+          creator: 'createOscillator',
+          args: [],
+          limits: {
+            frequency: {minValue: -sampleRate / 2, maxValue: sampleRate / 2},
+            detune: {
+              minValue: -Math.fround(1200 * Math.log2(mostPositiveFloat)),
+              maxValue: Math.fround(1200 * Math.log2(mostPositiveFloat))
+            }
+          }
+        },
+        {
+          creator: 'createPanner',
+          args: [],
+          limits: {
+            positionX: {
+              minValue: -mostPositiveFloat,
+              maxValue: mostPositiveFloat,
+            },
+            positionY: {
+              minValue: -mostPositiveFloat,
+              maxValue: mostPositiveFloat,
+            },
+            positionZ: {
+              minValue: -mostPositiveFloat,
+              maxValue: mostPositiveFloat,
+            },
+            orientationX: {
+              minValue: -mostPositiveFloat,
+              maxValue: mostPositiveFloat,
+            },
+            orientationY: {
+              minValue: -mostPositiveFloat,
+              maxValue: mostPositiveFloat,
+            },
+            orientationZ: {
+              minValue: -mostPositiveFloat,
+              maxValue: mostPositiveFloat,
+            }
+          },
+        },
+        {
+          creator: 'createConstantSource',
+          args: [],
+          limits: {
+            offset: {minValue: -mostPositiveFloat, maxValue: mostPositiveFloat}
+          }
+        },
+        // These nodes don't have AudioParams, but we want to test them anyway.
+        // Any arguments for the
+        // constructor are pretty much arbitrary; they just need to be valid.
+        {
+          creator: 'createBuffer',
+          args: [1, 1, sampleRate],
+        },
+        {creator: 'createIIRFilter', args: [[1, 2], [1, .9]]},
+        {
+          creator: 'createWaveShaper',
+          args: [],
+        },
+        {
+          creator: 'createConvolver',
+          args: [],
+        },
+        {
+          creator: 'createAnalyser',
+          args: [],
+        },
+        {
+          creator: 'createScriptProcessor',
+          args: [0],
+        },
+        {
+          creator: 'createPeriodicWave',
+          args: [Float32Array.from([0, 0]), Float32Array.from([1, 0])],
+        },
+        {
+          creator: 'createChannelSplitter',
+          args: [],
+        },
+        {
+          creator: 'createChannelMerger',
+          args: [],
+        },
+      ];
+
+      let testOnlineConfigs = [
+        {creator: 'createMediaElementSource', args: [new Audio()]},
+        {creator: 'createMediaStreamDestination', args: []}
+        // Can't currently test MediaStreamSource because we're using an offline
+        // context.
+      ];
+
+      // Create the contexts so we can use it in the following test.
+      audit.define('initialize', (task, should) => {
+        // Just any context so that we can create the nodes.
+        should(() => {
+          offlineContext = new OfflineAudioContext(1, 1, sampleRate);
+        }, 'Create offline context for tests').notThrow();
+        should(() => {
+          onlineContext = new AudioContext();
+        }, 'Create online context for tests').notThrow();
+        task.done();
+      });
+
+      // Create a task for each entry in testOfflineConfigs
+      for (let test in testOfflineConfigs) {
+        let config = testOfflineConfigs[test]
+        audit.define('Offline ' + config.creator, (function(c) {
+                       return (task, should) => {
+                         let node = offlineContext[c.creator](...c.args);
+                         testLimits(should, c.creator, node, c.limits);
+                         task.done();
+                       };
+                     })(config));
+      }
+
+      for (let test in testOnlineConfigs) {
+        let config = testOnlineConfigs[test]
+        audit.define('Online ' + config.creator, (function(c) {
+                       return (task, should) => {
+                         let node = onlineContext[c.creator](...c.args);
+                         testLimits(should, c.creator, node, c.limits);
+                         task.done();
+                       };
+                     })(config));
+      }
+
+      // Test the AudioListener params that were added for the automated Panner
+      audit.define('AudioListener', (task, should) => {
+        testLimits(should, '', offlineContext.listener, {
+          positionX: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          },
+          positionY: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          },
+          positionZ: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          },
+          forwardX: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          },
+          forwardY: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          },
+          forwardZ: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          },
+          upX: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          },
+          upY: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          },
+          upZ: {
+            minValue: -mostPositiveFloat,
+            maxValue: mostPositiveFloat,
+          }
+        });
+        task.done();
+      });
+
+      // Verify that we have tested all the create methods available on the
+      // context.
+      audit.define('verifyTests', (task, should) => {
+        let allNodes = new Set();
+        // Create the set of all "create" methods from the context.
+        for (let method in offlineContext) {
+          if (typeof offlineContext[method] === 'function' &&
+              method.substring(0, 6) === 'create') {
+            allNodes.add(method);
+          }
+        }
+
+        // Compute the difference between the set of all create methods on the
+        // context and the set of tests that we've run.
+        let diff = new Set([...allNodes].filter(x => !testedMethods.has(x)));
+
+        // Can't currently test a MediaStreamSourceNode, so remove it from the
+        // diff set.
+        diff.delete('createMediaStreamSource');
+
+        // It's a test failure if we didn't test all of the create methods in
+        // the context (except createMediaStreamSource, of course).
+        let output = [];
+        if (diff.size) {
+          for (let item of diff)
+            output.push(' ' + item.substring(6));
+        }
+
+        should(output.length === 0, 'Number of nodes not tested')
+            .message(': 0', ': ' + output);
+
+        task.done();
+      });
+
+      // Simple test of a few automation methods to verify we get warnings.
+      audit.define('automation', (task, should) => {
+        // Just use a DelayNode for testing because the audio param has finite
+        // limits.
+        should(() => {
+          let d = offlineContext.createDelay();
+
+          // The console output should have the warnings that we're interested
+          // in.
+          d.delayTime.setValueAtTime(-1, 0);
+          d.delayTime.linearRampToValueAtTime(2, 1);
+          d.delayTime.exponentialRampToValueAtTime(3, 2);
+          d.delayTime.setTargetAtTime(-1, 3, .1);
+          d.delayTime.setValueCurveAtTime(
+              Float32Array.from([.1, .2, 1.5, -1]), 4, .1);
+        }, 'Test automations (check console logs)').notThrow();
+        task.done();
+      });
+
+      audit.run();
+
+      // Is |object| an AudioParam?  We determine this by checking the
+      // constructor name.
+      function isAudioParam(object) {
+        return object && object.constructor.name === 'AudioParam';
+      }
+
+      // Does |limitOptions| exist and does it have valid values for the
+      // expected min and max values?
+      function hasValidLimits(limitOptions) {
+        return limitOptions && (typeof limitOptions.minValue === 'number') &&
+            (typeof limitOptions.maxValue === 'number');
+      }
+
+      // Check the min and max values for the AudioParam attribute named
+      // |paramName| for the |node|. The expected limits is given by the
+      // dictionary |limits|.  If some test fails, add the name of the failed
+      function validateAudioParamLimits(should, node, paramName, limits) {
+        let nodeName = node.constructor.name;
+        let parameter = node[paramName];
+        let prefix = nodeName + '.' + paramName;
+
+        let success = true;
+        if (hasValidLimits(limits[paramName])) {
+          // Verify that the min and max values for the parameter are correct.
+          let isCorrect = should(parameter.minValue, prefix + '.minValue')
+                              .beEqualTo(limits[paramName].minValue);
+          isCorrect = should(parameter.maxValue, prefix + '.maxValue')
+                          .beEqualTo(limits[paramName].maxValue) &&
+              isCorrect;
+
+          // Verify that the min and max attributes are read-only.  |testValue|
+          // MUST be a number that can be represented exactly the same way as
+          // both a double and single float.  A small integer works nicely.
+          const testValue = 42;
+          parameter.minValue = testValue;
+          let isReadOnly;
+          isReadOnly =
+              should(parameter.minValue, `${prefix}.minValue = ${testValue}`)
+                  .notBeEqualTo(testValue);
+
+          should(isReadOnly, prefix + '.minValue is read-only').beEqualTo(true);
+
+          isCorrect = isReadOnly && isCorrect;
+
+          parameter.maxValue = testValue;
+          isReadOnly =
+              should(parameter.maxValue, `${prefix}.maxValue = ${testValue}`)
+                  .notBeEqualTo(testValue);
+          should(isReadOnly, prefix + '.maxValue is read-only').beEqualTo(true);
+
+          isCorrect = isReadOnly && isCorrect;
+
+          // Now try to set the parameter outside the nominal range.
+          let newValue = 2 * limits[paramName].minValue - 1;
+
+          let isClipped = true;
+          let clippingTested = false;
+          // If the new value is beyond float the largest single-precision
+          // float, skip the test because Chrome throws an error.
+          if (newValue >= -mostPositiveFloat) {
+            parameter.value = newValue;
+            clippingTested = true;
+            isClipped =
+                should(
+                    parameter.value, 'Set ' + prefix + '.value = ' + newValue)
+                    .beEqualTo(parameter.minValue) &&
+                isClipped;
+          }
+
+          newValue = 2 * limits[paramName].maxValue + 1;
+
+          if (newValue <= mostPositiveFloat) {
+            parameter.value = newValue;
+            clippingTested = true;
+            isClipped =
+                should(
+                    parameter.value, 'Set ' + prefix + '.value = ' + newValue)
+                    .beEqualTo(parameter.maxValue) &&
+                isClipped;
+          }
+
+          if (clippingTested) {
+            should(
+                isClipped,
+                prefix + ' was clipped to lie within the nominal range')
+                .beEqualTo(true);
+          }
+
+          isCorrect = isCorrect && isClipped;
+
+          success = isCorrect && success;
+        } else {
+          // Test config didn't specify valid limits.  Fail this test!
+          should(
+              clippingTested,
+              'Limits for ' + nodeName + '.' + paramName +
+                  ' were correctly defined')
+              .beEqualTo(false);
+
+          success = false;
+        }
+
+        return success;
+      }
+
+      // Test all of the AudioParams for |node| using the expected values in
+      // |limits|. |creatorName| is the name of the method to create the node,
+      // and is used to keep trakc of which tests we've run.
+      function testLimits(should, creatorName, node, limits) {
+        let nodeName = node.constructor.name;
+        testedMethods.add(creatorName);
+
+        let success = true;
+
+        // List of all of the AudioParams that were tested.
+        let audioParams = [];
+
+        // List of AudioParams that failed the test.
+        let incorrectParams = [];
+
+        // Look through all of the keys for the node and extract just the
+        // AudioParams
+        Object.keys(node.__proto__).forEach(function(paramName) {
+          if (isAudioParam(node[paramName])) {
+            audioParams.push(paramName);
+            let isValid = validateAudioParamLimits(
+                should, node, paramName, limits, incorrectParams);
+            if (!isValid)
+              incorrectParams.push(paramName);
+
+            success = isValid && success;
+          }
+        });
+
+        // Print an appropriate message depending on whether there were
+        // AudioParams defined or not.
+        if (audioParams.length) {
+          let message =
+              'Nominal ranges for AudioParam(s) of ' + node.constructor.name;
+          should(success, message)
+              .message('are correct', 'are incorrect for: ' + +incorrectParams);
+          return success;
+        } else {
+          should(!limits, nodeName)
+              .message(
+                  'has no AudioParams as expected',
+                  'has no AudioParams but test expected ' + limits);
+        }
+      }
+    </script>
+  </body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamsetValueCurveexceptionsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt       2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions-expected.txt  2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> 
</span><span class="cx"> PASS # AUDIT TASK RUNNER STARTED.
</span><span class="cx"> PASS Executing "setValueCurve"
</span><ins>+PASS Executing "value setter"
</ins><span class="cx"> PASS Executing "automations"
</span><span class="cx"> PASS Executing "catch-exception"
</span><span class="cx"> PASS Executing "start-end"
</span><span class="lines">@@ -15,6 +16,10 @@
</span><span class="cx"> PASS   setTargetAtTime(1, 0.018750, 1) threw NotSupportedError: "Events are overlapping".
</span><span class="cx"> PASS   setValueAtTime(1, 0.026250) did not throw an exception.
</span><span class="cx"> PASS < [setValueCurve] All assertions passed. (total 6 assertions)
</span><ins>+PASS > [value setter]
+PASS   setValueCurveAtTime(curve, 0, 0.025) did not throw an exception.
+PASS   value setter threw NotSupportedError: "Events are overlapping".
+PASS < [value setter] All assertions passed. (total 2 assertions)
</ins><span class="cx"> PASS > [automations]
</span><span class="cx"> PASS   linearRampToValueAtTime(1, 0.0125) did not throw an exception.
</span><span class="cx"> PASS   exponentialRampToValueAtTime(1, 0.025) did not throw an exception.
</span><span class="lines">@@ -59,5 +64,5 @@
</span><span class="cx"> PASS   setValueCurveAtTime([1], 0, 0.01) threw InvalidStateError: "Array must have a length of at least 2".
</span><span class="cx"> PASS   setValueCurveAtTime([1,2], 0, 0.01) did not throw an exception.
</span><span class="cx"> PASS < [curve lengths] All assertions passed. (total 3 assertions)
</span><del>-PASS # AUDIT TASK RUNNER FINISHED: 6 tasks ran successfully.
</del><ins>+PASS # AUDIT TASK RUNNER FINISHED: 7 tasks ran successfully.
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceaudioparamsetValueCurveexceptionshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html       2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html  2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -20,7 +20,6 @@
</span><span class="cx">       let audit = Audit.createTaskRunner();
</span><span class="cx"> 
</span><span class="cx">       audit.define('setValueCurve', (task, should) => {
</span><del>-        let success = true;
</del><span class="cx">         let context =
</span><span class="cx">             new OfflineAudioContext(1, testDurationFrames, sampleRate);
</span><span class="cx">         let g = context.createGain();
</span><span class="lines">@@ -79,6 +78,37 @@
</span><span class="cx">         task.done();
</span><span class="cx">       });
</span><span class="cx"> 
</span><ins>+      audit.define('value setter', (task, should) => {
+        let context =
+            new OfflineAudioContext(1, testDurationFrames, sampleRate);
+        let g = context.createGain();
+        let curve = new Float32Array(2);
+
+        // Start time and duration for setValueCurveAtTime
+        let curveStartTime = 0.;
+        let duration = 0.2 * testDurationSec;
+
+        // Some time that is known to be during the setValueCurveTime interval.
+        let automationTime = 0.;
+
+        should(
+            () => {
+              g.gain.setValueCurveAtTime(curve, curveStartTime, duration);
+            },
+            'setValueCurveAtTime(curve, ' + curveStartTime + ', ' + duration +
+                ')')
+            .notThrow();
+
+        should(
+            function() {
+              g.gain.value = 0.;
+            },
+            'value setter')
+            .throw(DOMException, 'NotSupportedError');
+
+        task.done();
+      });
+
</ins><span class="cx">       audit.define('automations', (task, should) => {
</span><span class="cx">         let context =
</span><span class="cx">             new OfflineAudioContext(1, testDurationFrames, sampleRate);
</span><span class="lines">@@ -175,7 +205,6 @@
</span><span class="cx">       audit.define('catch-exception', (task, should) => {
</span><span class="cx">         // Verify that the curve isn't inserted into the time line even if we
</span><span class="cx">         // catch the exception.
</span><del>-        let success = true;
</del><span class="cx">         let context =
</span><span class="cx">             new OfflineAudioContext(1, testDurationFrames, sampleRate);
</span><span class="cx">         let gain = context.createGain();
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfacecancelscheduledvaluesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values-expected.txt (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values-expected.txt   2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values-expected.txt      2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -1,7 +1,13 @@
</span><span class="cx"> 
</span><span class="cx"> PASS # AUDIT TASK RUNNER STARTED.
</span><ins>+PASS Executing "cancel-time"
</ins><span class="cx"> PASS Executing "cancel1"
</span><span class="cx"> PASS Audit report
</span><ins>+PASS > [cancel-time] handle cancelTime values
+PASS   cancelScheduledValues(-1) threw RangeError: "cancelTime must be a positive value".
+PASS   cancelScheduledValues(NaN) threw TypeError: "The provided value is non-finite".
+PASS   cancelScheduledValues(Infinity) threw TypeError: "The provided value is non-finite".
+PASS < [cancel-time] All assertions passed. (total 3 assertions)
</ins><span class="cx"> PASS > [cancel1] cancel setValueCurve
</span><span class="cx"> PASS   cancelTime is after curve start is greater than 0.25.
</span><span class="cx"> PASS   cancelTime is before curve ends is less than 0.5.
</span><span class="lines">@@ -15,5 +21,5 @@
</span><span class="cx"> PASS   output[2000:2999] contains only the constant 1.5.
</span><span class="cx"> PASS   output[3000:] contains only the constant 3.
</span><span class="cx"> PASS < [cancel1] All assertions passed. (total 11 assertions)
</span><del>-PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully.
</del><ins>+PASS # AUDIT TASK RUNNER FINISHED: 2 tasks ran successfully.
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfacecancelscheduledvalueshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values.html (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values.html   2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/cancel-scheduled-values.html      2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -17,6 +17,38 @@
</span><span class="cx">       let audit = Audit.createTaskRunner();
</span><span class="cx"> 
</span><span class="cx">       audit.define(
</span><ins>+          {label: 'cancel-time', description: 'handle cancelTime values'},
+          (task, should) => {
+            let context = new OfflineAudioContext({
+              numberOfChannels: 1,
+              length: renderFrames,
+              sampleRate: sampleRate
+            });
+
+            let src = new ConstantSourceNode(context);
+            src.connect(context.destination);
+
+            should(
+                () => src.offset.cancelScheduledValues(-1),
+                'cancelScheduledValues(-1)')
+                .throw(RangeError);
+
+            // These are TypeErrors because |cancelTime| is a
+            // double, not unrestricted double.
+            should(
+                () => src.offset.cancelScheduledValues(NaN),
+                'cancelScheduledValues(NaN)')
+                .throw(TypeError);
+
+            should(
+                () => src.offset.cancelScheduledValues(Infinity),
+                'cancelScheduledValues(Infinity)')
+                .throw(TypeError);
+
+            task.done();
+          });
+
+      audit.define(
</ins><span class="cx">           {label: 'cancel1', description: 'cancel setValueCurve'},
</span><span class="cx">           (task, should) => {
</span><span class="cx">             let context = new OfflineAudioContext({
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceeventinsertionexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt   2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion-expected.txt      2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx"> PASS   Linear+SetTarget: setTargetAtTime(0, 0.015625, 0.1) did not throw an exception.
</span><span class="cx"> PASS   Linear+SetTarget: At time 0.015564 (frame 255) output is 2.992188 within an error of 0.
</span><span class="cx"> PASS   Linear+SetTarget: At time 0.015625 (frame 256) output is equal to 100.
</span><del>-PASS   Linear+SetTarget: At time 0.015625 (frame 256) and later equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":1.7807e-7}.
</del><ins>+PASS   Linear+SetTarget: At time 0.015625 (frame 256) and later equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":2.6694e-7}.
</ins><span class="cx"> PASS < [Linear + SetTarget] All assertions passed. (total 7 assertions)
</span><span class="cx"> PASS > [Multiple linear ramps at the same time] Verify output
</span><span class="cx"> PASS   Multiple linear ramps: setValueAtTime(1, 0) did not throw an exception.
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfaceeventinsertionhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html   2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/event-insertion.html      2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -206,7 +206,7 @@
</span><span class="cx">                           `At time ${eventTime} (frame ${
</span><span class="cx">                                                          eventFrame
</span><span class="cx">                                                        }) and later`)
</span><del>-                      .beCloseToArray(expected, {relativeThreshold: 1.7807e-7});
</del><ins>+                      .beCloseToArray(expected, {relativeThreshold: 2.6694e-7});
</ins><span class="cx">                 })
</span><span class="cx">                 .then(() => task.done());
</span><span class="cx">           });
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioparaminterfacew3cimportlog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log 2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/w3c-import.log    2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -15,6 +15,7 @@
</span><span class="cx"> ------------------------------------------------------------------------
</span><span class="cx"> List of files:
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/adding-events.html
</span><ins>+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-cancel-and-hold.html
</ins><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-close.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-connect-audioratesignal.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-exceptional-values.html
</span><span class="lines">@@ -22,6 +23,7 @@
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-large-endtime.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-linearRampToValueAtTime.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-method-chaining.html
</span><ins>+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-nominal-range.html
</ins><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setTargetAtTime.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueAtTime.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-setValueCurve-exceptions.html
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioworkletinterfaceaudioworkletthrowonmessagehttpsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https-expected.txt (0 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https-expected.txt                              (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https-expected.txt 2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+
+PASS Throwing in an onmessage handler in the AudioWorkletGlobalScope shouldn't stop AudioWorkletProcessor
+
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioworkletinterfaceaudioworkletthrowonmessagehttpshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https.html (0 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https.html                              (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https.html 2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8" />
+    <title>
+      Test the behaviour of AudioWorkletProcessor when an `onmessage` handler
+      throws.
+    </title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/webaudio/js/helpers.js"></script>
+  </head>
+
+  <body>
+    <script id="processor" type="worklet">
+      registerProcessor("test-throw", class param extends AudioWorkletProcessor {
+        constructor() {
+          super()
+          this.i = 0;
+          this.port.onmessage = function(arg) {
+            throw "asdasd";
+          }
+        }
+        process(input, output, parameters) {
+          this.i++;
+          this.port.postMessage(this.i);
+          return true;
+        }
+      });
+    </script>
+    <script>
+      var latestIndexReceived = 0;
+      var node = null;
+      var ac = null;
+      promise_setup(function() {
+        ac = new AudioContext();
+        var url = URLFromScriptsElements(["processor"]);
+        return ac.audioWorklet.addModule(url).then(function() {
+          node = new AudioWorkletNode(ac, "test-throw");
+          node.port.onmessage = function(e) {
+            latestIndexReceived = parseInt(e.data);
+          };
+        });
+      });
+      promise_test(async t => {
+        var currentIndex = latestIndexReceived;
+        await t.step_wait(() => {
+          return latestIndexReceived > currentIndex;
+        }, "Process is still being called");
+
+        node.port.postMessage("asdasd"); // This throws on the processor side.
+        node.onprocessorerror = function() {
+          assert_true(false, "onprocessorerror must not be called.");
+        };
+        currentIndex = latestIndexReceived;
+        await t.step_wait(() => {
+          return latestIndexReceived > currentIndex + 2;
+        }, "Process is still being called");
+      }, `Throwing in an onmessage handler in the AudioWorkletGlobalScope shouldn't stop AudioWorkletProcessor`);
+    </script>
+  </body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioworkletinterfaceprocessorsw3cimportlog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log    2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/w3c-import.log       2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -22,6 +22,7 @@
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-super.js
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-singleton.js
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-super-after-new.js
</span><ins>+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js
</ins><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheaudioworkletinterfacew3cimportlog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log       2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/w3c-import.log  2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -21,7 +21,9 @@
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-messageport.https.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-postmessage-sharedarraybuffer.https.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-postmessage-sharedarraybuffer.https.html.headers
</span><ins>+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-registerprocessor-called-on-globalthis.https.html
</ins><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-suspend.https.html
</span><ins>+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-throw-onmessage.https.html
</ins><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-sample-rate.https.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletglobalscope-timing-info.https.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-audioworklet-interface/audioworkletnode-automatic-pull.https.html
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithebiquadfilternodeinterfacebiquadautomationexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt   2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation-expected.txt      2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -11,7 +11,7 @@
</span><span class="cx"> PASS   Output of bandpass filter with frequency automation equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0.000005,"relativeThreshold":0}.
</span><span class="cx"> PASS < [automate-freq] All assertions passed. (total 1 assertions)
</span><span class="cx"> PASS > [automate-q]
</span><del>-PASS   Output of bandpass filter with Q automation equals [expected array] with an element-wise tolerance of {"absoluteThreshold":9.8348e-7,"relativeThreshold":0}.
</del><ins>+PASS   Output of bandpass filter with Q automation equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0.000001,"relativeThreshold":0}.
</ins><span class="cx"> PASS < [automate-q] All assertions passed. (total 1 assertions)
</span><span class="cx"> PASS > [automate-gain]
</span><span class="cx"> PASS   Output of lowshelf filter with gain automation equals [expected array] with an element-wise tolerance of {"absoluteThreshold":0.000028,"relativeThreshold":0}.
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithebiquadfilternodeinterfacebiquadautomationhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html   2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-automation.html      2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -218,7 +218,7 @@
</span><span class="cx"> 
</span><span class="cx">         context.startRendering()
</span><span class="cx">             .then(createFilterVerifier(
</span><del>-                should, createBandpassFilter, 9.8348e-7, parameters,
</del><ins>+                should, createBandpassFilter, 1.0133e-6, parameters,
</ins><span class="cx">                 b.getChannelData(0),
</span><span class="cx">                 'Output of bandpass filter with Q automation'))
</span><span class="cx">             .then(() => task.done());
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheconstantsourcenodeinterfacetestconstantsourcenodehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html   2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html      2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -124,7 +124,7 @@
</span><span class="cx">       var result = e.renderedBuffer.getChannelData(0);
</span><span class="cx">       var expected = buffer.getChannelData(0);
</span><span class="cx">       for (var i = 0; i < 2048; ++i) {
</span><del>-        assert_true(Math.abs(result[i] - expected[i]) < 1e-6, "sample " + i + " should equal " + expected[i]);
</del><ins>+        assert_true(Math.abs(result[i] - expected[i]) < 1.342e-6, "sample " + i + " should equal " + expected[i]);
</ins><span class="cx">       }
</span><span class="cx">     });
</span><span class="cx">     t.done();
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheconvolvernodeinterfacerealtimeconvexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv-expected.txt (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv-expected.txt  2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv-expected.txt     2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -3,7 +3,7 @@
</span><span class="cx"> PASS Executing "test"
</span><span class="cx"> PASS Audit report
</span><span class="cx"> PASS > [test] Test convolver with real-time context
</span><del>-PASS   SNR is greater than or equal to 83.
</del><ins>+PASS   SNR is greater than or equal to 77.03.
</ins><span class="cx"> PASS < [test] All assertions passed. (total 1 assertions)
</span><span class="cx"> PASS # AUDIT TASK RUNNER FINISHED: 1 tasks ran successfully.
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheconvolvernodeinterfacerealtimeconvhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv.html (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv.html  2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv.html     2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -22,7 +22,7 @@
</span><span class="cx">       // teh platform and browser.  Don't set this value to be to much lower
</span><span class="cx">       // than this. It probably indicates a fairly inaccurate convolver or
</span><span class="cx">       // constant source node automations that should be fixed instead.
</span><del>-      const minRequiredSNR = 83;
</del><ins>+      const minRequiredSNR = 77.03;
</ins><span class="cx"> 
</span><span class="cx">       // To test the real-time convolver, we convolve two square pulses together
</span><span class="cx">       // to produce a triangular pulse.  To verify the result is correct we
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithepannernodeinterfacepannernodesetpositionthrowsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws-expected.txt (0 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws-expected.txt                             (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws-expected.txt        2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+
+FAIL setPosition x assert_throws_js: function "() => panner.setPosition(2 * FLT_MAX, 0, 0)" did not throw
+FAIL setPosition y assert_throws_js: function "() => panner.setPosition(0, -2 * FLT_MAX, 0)" did not throw
+FAIL setPosition z assert_throws_js: function "() => panner.setPosition(0, 0, 2 * FLT_MAX)" did not throw
+FAIL setOrientation x assert_throws_js: function "() => panner.setOrientation(-2 * FLT_MAX, 0, 0)" did not throw
+FAIL setOrientation y assert_throws_js: function "() => panner.setOrientation(0, 2 * FLT_MAX, 0)" did not throw
+FAIL setOrientation z assert_throws_js: function "() => panner.setOrientation(0, 0, -2 * FLT_MAX)" did not throw
+
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithepannernodeinterfacepannernodesetpositionthrowshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws.html (0 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws.html                             (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws.html        2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+<!doctype html>
+<meta charset=utf-8>
+<title>Test PannerNode.setPosition() throws with parameter out of range of float</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+// https://webaudio.github.io/web-audio-api/#dom-pannernode-setposition
+// setPosition(x, y, z) "is equivalent to setting positionX.value,
+// positionY.value, and positionZ.value directly with the given x, y, and z
+// values, respectively."  setPosition() parameters are double, but the
+// AudioParam value setter has a float parameter, so out of range values
+// throw.
+const FLT_MAX = 3.40282e+38;
+let panner;
+setup(() => {
+  const ctx = new OfflineAudioContext({length: 1, sampleRate: 24000});
+  panner = ctx.createPanner();
+});
+test(() => {
+  assert_throws_js(TypeError, () => panner.setPosition(2 * FLT_MAX, 0, 0));
+}, "setPosition x");
+test(() => {
+  assert_throws_js(TypeError, () => panner.setPosition(0, -2 * FLT_MAX, 0));
+}, "setPosition y");
+test(() => {
+  assert_throws_js(TypeError, () => panner.setPosition(0, 0, 2 * FLT_MAX));
+}, "setPosition z");
+test(() => {
+  assert_throws_js(TypeError, () => panner.setOrientation(-2 * FLT_MAX, 0, 0));
+}, "setOrientation x");
+test(() => {
+  assert_throws_js(TypeError, () => panner.setOrientation(0, 2 * FLT_MAX, 0));
+}, "setOrientation y");
+test(() => {
+  assert_throws_js(TypeError, () => panner.setOrientation(0, 0, -2 * FLT_MAX));
+}, "setOrientation z");
+</script>
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapithepannernodeinterfacew3cimportlog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log 2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/w3c-import.log    2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -28,4 +28,5 @@
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/panner-equalpower.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/panner-rolloff-clamping.html
</span><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-basic.html
</span><ins>+/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/pannernode-setposition-throws.html
</ins><span class="cx"> /LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-pannernode-interface/test-pannernode-automation.html
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestswebaudiotheaudioapitheperiodicwaveinterfaceperiodicWavehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html (278960 => 278961)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html    2021-06-16 22:27:05 UTC (rev 278960)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webaudio/the-audio-api/the-periodicwave-interface/periodicWave.html       2021-06-16 22:37:01 UTC (rev 278961)
</span><span class="lines">@@ -2,7 +2,7 @@
</span><span class="cx"> <html>
</span><span class="cx">   <head>
</span><span class="cx">     <title>
</span><del>-      Test Constructor: MediaStreamAudioDestinationNode
</del><ins>+      Test Constructor: PeriodicWave
</ins><span class="cx">     </title>
</span><span class="cx">     <script src="/resources/testharness.js"></script>
</span><span class="cx">     <script src="/resources/testharnessreport.js"></script>
</span></span></pre>
</div>
</div>

</body>
</html>