Skip to content

Commit 135587a

Browse files
committed
Bug 1979017 [wpt PR 53950] - [webaudio-testharness] Migrate iirfilter-getFrequencyResponse.html, a=testonly
Automatic update from web-platform-tests [webaudio-testharness] Migrate iirfilter-getFrequencyResponse.html (#53950) This CL rewrites the IIRFilterNode getFrequencyResponse() test to use testharness.js instead of the legacy audit.js framework. The logic and thresholds remain unchanged, preserving test validity. This migration helps reduce dependencies on audit.js and aligns with Web Platform Test standards. Bug: 396477778 Change-Id: I093a0ccd8792a5813c47e46148b09c7410474e1f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6688066 Reviewed-by: Hongchan Choi <hongchanchromium.org> Auto-Submit: Punith Nayak <punithbnayakchromium.org> Reviewed-by: Michael Wilson <mjwilsonchromium.org> Commit-Queue: Punith Nayak <punithbnayakchromium.org> Cr-Commit-Position: refs/heads/main{#1491212} Co-authored-by: punithbnayak <punithbnayakchromium.org> -- wpt-commits: 950a214d5871ffbf1d38e18b9b48d41dac5bfcf4 wpt-pr: 53950 UltraBlame original commit: f854d3ceb6e365bdcfe9a689d65cf665be773d69
1 parent 7131d4f commit 135587a

File tree

2 files changed

+107
-102
lines changed

2 files changed

+107
-102
lines changed

testing/web-platform/tests/webaudio/resources/audit-util.js

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,40 @@ function assert_strict_constant_value(array, constantValue, message) {
278278

279279
function assert_array_approximately_equals(
280280
actual, expected, threshold, message) {
281-
assert_equals(
282-
actual.length,
283-
expected.length,
284-
`${message} - buffer lengths must match`);
285-
for (let i = 0; i < actual.length; ++i) {
286-
assert_approx_equals(
287-
actual[i], expected[i], threshold,
288-
`${message} at index ${i}`);
289-
}
281+
assert_equals(
282+
actual.length,
283+
expected.length,
284+
`${message} - buffer lengths must match`);
285+
for (let i = 0; i < actual.length; ++i) {
286+
assert_approx_equals(
287+
actual[i], expected[i], threshold,
288+
`${message} at index ${i}`);
289+
}
290+
}
291+
292+
293+
294+
295+
296+
297+
298+
299+
300+
301+
302+
303+
304+
305+
function assert_close_to_array(actual, expected, epsilon, desc) {
306+
assert_equals(
307+
actual.length,
308+
expected.length,
309+
`${desc}: length mismatch`);
310+
for (let i = 0; i < actual.length; ++i) {
311+
const diff = Math.abs(actual[i] - expected[i]);
312+
assert_less_than_equal(
313+
diff,
314+
epsilon,
315+
`${desc}[${i}] |${actual[i]} - ${expected[i]}| = ${diff} > ${epsilon}`);
316+
}
290317
}

testing/web-platform/tests/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-getFrequencyResponse.html

Lines changed: 71 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,17 @@
77
<script src="/resources/testharness.js"></script>
88
<script src="/resources/testharnessreport.js"></script>
99
<script src="../../resources/audit-util.js"></script>
10-
<script src="../../resources/audit.js"></script>
1110
<script src="../../resources/biquad-filters.js"></script>
1211
</head>
1312
<body>
14-
<script id="layout-test-code">
15-
let sampleRate = 48000;
13+
<script>
14+
15+
const sampleRate = 48000;
1616
// Some short duration; we're not actually looking at the rendered output.
17-
let testDurationSec = 0.01;
17+
const testDurationSec = 0.01;
1818

1919
// Number of frequency samples to take.
20-
let numberOfFrequencies = 1000;
21-
22-
let audit = Audit.createTaskRunner();
23-
20+
const numberOfFrequencies = 1000;
2421

2522
// Compute a set of linearly spaced frequencies.
2623
function createFrequencies(nFrequencies, sampleRate) {
@@ -35,18 +32,17 @@
3532
return frequencies;
3633
}
3734

38-
audit.define('1-pole IIR', (task, should) => {
39-
let context = new OfflineAudioContext(
35+
test(t => {
36+
const context = new OfflineAudioContext(
4037
1, testDurationSec * sampleRate, sampleRate);
38+
const iir = context.createIIRFilter([1], [1, -0.9]);
4139

42-
let iir = context.createIIRFilter([1], [1, -0.9]);
43-
let frequencies =
44-
createFrequencies(numberOfFrequencies, context.sampleRate);
45-
46-
let iirMag = new Float32Array(numberOfFrequencies);
47-
let iirPhase = new Float32Array(numberOfFrequencies);
48-
let trueMag = new Float32Array(numberOfFrequencies);
49-
let truePhase = new Float32Array(numberOfFrequencies);
40+
const frequencies = createFrequencies(
41+
numberOfFrequencies, context.sampleRate);
42+
const iirMag = new Float32Array(numberOfFrequencies);
43+
const iirPhase = new Float32Array(numberOfFrequencies);
44+
const trueMag = new Float32Array(numberOfFrequencies);
45+
const truePhase = new Float32Array(numberOfFrequencies);
5046

5147
// The IIR filter is
5248
// H(z) = 1/(1 - 0.9*z^(-1)).
@@ -60,10 +56,9 @@
6056
// The phase is
6157
// arg(H(exp(j*w)) = atan(0.9*sin(w)/(.9*cos(w)-1))
6258

63-
let frequencyScale = Math.PI / (sampleRate / 2);
64-
59+
const frequencyScale = Math.PI / (sampleRate / 2);
6560
for (let k = 0; k < frequencies.length; ++k) {
66-
let omega = frequencyScale * frequencies[k];
61+
const omega = frequencyScale * frequencies[k];
6762
trueMag[k] = 1 / Math.sqrt(1.81 - 1.8 * Math.cos(omega));
6863
truePhase[k] =
6964
Math.atan(0.9 * Math.sin(omega) / (0.9 * Math.cos(omega) - 1));
@@ -72,88 +67,71 @@
7267
iir.getFrequencyResponse(frequencies, iirMag, iirPhase);
7368

7469
// Thresholds were experimentally determined.
75-
should(iirMag, '1-pole IIR Magnitude Response')
76-
.beCloseToArray(trueMag, {absoluteThreshold: 2.8611e-6});
77-
should(iirPhase, '1-pole IIR Phase Response')
78-
.beCloseToArray(truePhase, {absoluteThreshold: 1.7882e-7});
79-
80-
task.done();
81-
});
82-
83-
audit.define('compare IIR and biquad', (task, should) => {
70+
assert_close_to_array(
71+
iirMag, trueMag, 2.8611e-6, '1‑pole IIR magnitude response ' +
72+
'should be closed to calculated magnitude response');
73+
assert_close_to_array(
74+
iirPhase, truePhase, 1.7882e-7, '1‑pole IIR phase response ' +
75+
' should be closed to calculated phase response');
76+
}, '1‑pole IIR getFrequencyResponse() matches analytic response');
77+
78+
test(t => {
8479
// Create an IIR filter equivalent to the biquad filter. Compute the
8580
// frequency response for both and verify that they are the same.
86-
let context = new OfflineAudioContext(
81+
const context = new OfflineAudioContext(
8782
1, testDurationSec * sampleRate, sampleRate);
8883

89-
let biquad = context.createBiquadFilter();
90-
let coef = createFilter(
91-
biquad.type, biquad.frequency.value / (context.sampleRate / 2),
92-
biquad.Q.value, biquad.gain.value);
84+
const biquad = context.createBiquadFilter();
85+
const coef = createFilter(
86+
biquad.type,
87+
biquad.frequency.value / (context.sampleRate / 2),
88+
biquad.Q.value,
89+
biquad.gain.value);
9390

94-
let iir = context.createIIRFilter(
91+
const iir = context.createIIRFilter(
9592
[coef.b0, coef.b1, coef.b2], [1, coef.a1, coef.a2]);
9693

97-
let frequencies =
98-
createFrequencies(numberOfFrequencies, context.sampleRate);
99-
let biquadMag = new Float32Array(numberOfFrequencies);
100-
let biquadPhase = new Float32Array(numberOfFrequencies);
101-
let iirMag = new Float32Array(numberOfFrequencies);
102-
let iirPhase = new Float32Array(numberOfFrequencies);
94+
const frequencies = createFrequencies(
95+
numberOfFrequencies, context.sampleRate);
96+
const biquadMag = new Float32Array(numberOfFrequencies);
97+
const biquadPhase = new Float32Array(numberOfFrequencies);
98+
const iirMag = new Float32Array(numberOfFrequencies);
99+
const iirPhase = new Float32Array(numberOfFrequencies);
103100

104101
biquad.getFrequencyResponse(frequencies, biquadMag, biquadPhase);
105102
iir.getFrequencyResponse(frequencies, iirMag, iirPhase);
106-
107-
// Thresholds were experimentally determined.
108-
should(iirMag, 'IIR Magnitude Response').beCloseToArray(biquadMag, {
109-
absoluteThreshold: 2.7419e-5
110-
});
111-
should(iirPhase, 'IIR Phase Response').beCloseToArray(biquadPhase, {
112-
absoluteThreshold: 2.7657e-5
113-
});
114-
115-
task.done();
116-
});
117-
118-
audit.define(
119-
{
120-
label: 'getFrequencyResponse',
121-
description: 'Test out-of-bounds frequency values'
122-
},
123-
(task, should) => {
124-
let context = new OfflineAudioContext(1, 1, sampleRate);
125-
let filter = new IIRFilterNode(
126-
context, {feedforward: [1], feedback: [1, -.9]});
127-
128-
// Frequencies to test. These are all outside the valid range of
129-
// frequencies of 0 to Nyquist.
130-
let freq = new Float32Array(2);
131-
freq[0] = -1;
132-
freq[1] = context.sampleRate / 2 + 1;
133-
134-
let mag = new Float32Array(freq.length);
135-
let phase = new Float32Array(freq.length);
136-
137-
filter.getFrequencyResponse(freq, mag, phase);
138-
139-
// Verify that the returned magnitude and phase entries are alL NaN
140-
// since the frequencies are outside the valid range
141-
for (let k = 0; k < mag.length; ++k) {
142-
should(mag[k],
143-
'Magnitude response at frequency ' + freq[k])
144-
.beNaN();
145-
}
146-
147-
for (let k = 0; k < phase.length; ++k) {
148-
should(phase[k],
149-
'Phase response at frequency ' + freq[k])
150-
.beNaN();
151-
}
152-
153-
task.done();
154-
});
155-
156-
audit.run();
103+
// Thresholds were experimentally determined.
104+
assert_close_to_array(
105+
iirMag, biquadMag, 2.7419e-5, 'IIR magnitude response should be' +
106+
'close to Biquad magnitude response');
107+
assert_close_to_array(
108+
iirPhase, biquadPhase, 2.7657e-5, 'IIR phase response should be' +
109+
'close to Biquad phase response');
110+
}, 'IIR filter equivalent to biquad has matching frequency response');
111+
112+
test(t => {
113+
const context = new OfflineAudioContext(1, 1, sampleRate);
114+
const filter = new IIRFilterNode(
115+
context, {feedforward: [1], feedback: [1, -0.9]});
116+
// Frequencies to test. These are all outside the valid range of
117+
// frequencies of 0 to Nyquist.
118+
const freq = new Float32Array([-1, context.sampleRate / 2 + 1]);
119+
const mag = new Float32Array(freq.length);
120+
const phase = new Float32Array(freq.length);
121+
122+
filter.getFrequencyResponse(freq, mag, phase);
123+
124+
// Verify that the returned magnitude and phase entries are all NaN
125+
// since the frequencies are outside the valid range
126+
for (let k = 0; k < freq.length; ++k) {
127+
assert_true(
128+
Number.isNaN(mag[k]),
129+
`Magnitude response at f=${freq[k]} should be NaN`);
130+
assert_true(
131+
Number.isNaN(phase[k]),
132+
`Phase response at f=${freq[k]} should be NaN`);
133+
}
134+
}, 'Out‑of‑range frequency values yield NaN responses');
157135
</script>
158136
</body>
159137
</html>

0 commit comments

Comments
 (0)