OLD | NEW |
1 <!doctype html> | 1 <!doctype html> |
2 <html> | 2 <html> |
3 <head> | 3 <head> |
4 <title>Test Oscillator Node: sine</title> | 4 <title>Test Oscillator Node: sine</title> |
5 <script src="resources/compatibility.js"></script> | 5 <script src="resources/compatibility.js"></script> |
6 <script src="resources/buffer-loader.js"></script> | 6 <script src="resources/buffer-loader.js"></script> |
7 <script src="../resources/js-test.js"></script> | 7 <script src="../resources/js-test.js"></script> |
8 <script src="resources/oscillator-testing.js"></script> | 8 <script src="resources/oscillator-testing.js"></script> |
9 </head> | 9 </head> |
10 | 10 |
11 <body> | 11 <body> |
12 <script> | 12 <script> |
13 // See oscillator-sine.html for more info on the actual wave shape. | 13 description("Test Sine Oscillator with Exponential Sweep"); |
14 // | 14 |
15 // This test is a partial duplicate of oscillator-sine but is designed t
o be less sensitive | 15 var tester = OscillatorTestingUtils; |
16 // to the actual output versus the reference. Instead of requiring an ex
act match, we check | |
17 // several criteria to pass the test. The SNR between the actual and exp
ected signals must | |
18 // be large enough. The maximum difference must be below a threshold, a
nd the actual number | |
19 // of points that are different must be below a threshold. | |
20 | 16 |
21 var sampleRate = 44100.0; | 17 // The thresholds are experimentally determined. |
22 var nyquist = 0.5 * sampleRate; | 18 tester.setThresholds({snr: 86.58, maxDiff: 2.9, diffCount: 5850}); |
23 var lengthInSeconds = 4; | 19 tester.runTest("sine"); |
24 var lowFrequency = 10; | 20 successfullyParsed = true; |
25 var highFrequency = nyquist + 2000; // go slightly higher than nyquist t
o make sure we generate silence there | |
26 var context = 0; | |
27 var reference = 0; | |
28 var renderedData = 0; | |
29 var signalPower = 0; | |
30 var noisePower = 0; | |
31 | |
32 // Scaling factor for converting the 16-bit WAV data to float (and vice-
versa). | |
33 var waveScaleFactor = 32768; | |
34 | |
35 // Thresholds for verifying the test passes. The thresholds are experim
entally determined. | |
36 | |
37 // SNR must be greater than this to pass the test. | |
38 // Q: Why is the SNR threshold not infinity? | |
39 // A: The reference result is a 16-bit WAV file, so it won't compare exa
ctly with the | |
40 // floating point result. | |
41 var thresholdSNR = 86.58; | |
42 | |
43 // Max diff must be less than this to pass the test. | |
44 var thresholdDiff = 2.9 / waveScaleFactor; | |
45 | |
46 // Count the number of differences between the expected and actual resul
t. The tests passes | |
47 // if the count is less than this threshold. | |
48 var thresholdDiffCount = 5850; | |
49 | |
50 function db(sPower, nPower) | |
51 { | |
52 if (nPower == 0 && sPower > 0) { | |
53 return 1000; | |
54 } | |
55 return 10 * Math.log10(sPower / nPower); | |
56 } | |
57 | |
58 function checkResult (event) { | |
59 renderedData = event.renderedBuffer.getChannelData(0); | |
60 // Compute signal to noise ratio between the result and the referenc
e. Also keep track | |
61 // of the max difference (and position). | |
62 | |
63 var maxError = -1; | |
64 var errorPosition = -1; | |
65 var diffCount = 0; | |
66 | |
67 for (var k = 0; k < renderedData.length; ++k) { | |
68 var diff = renderedData[k] - reference[k]; | |
69 noisePower += diff * diff; | |
70 signalPower += reference[k] * reference[k]; | |
71 if (Math.abs(diff) > maxError) { | |
72 maxError = Math.abs(diff); | |
73 errorPosition = k; | |
74 } | |
75 // The reference file is a 16-bit WAV file, so we will never get
an exact match | |
76 // between it and the actual floating-point result. | |
77 if (diff > 1/waveScaleFactor) { | |
78 diffCount++; | |
79 } | |
80 } | |
81 | |
82 var snr = db(signalPower, noisePower); | |
83 if (snr < thresholdSNR) { | |
84 testFailed("Expected SNR of " + thresholdSNR + " dB, but actual
SNR is " + snr + " dB"); | |
85 } else { | |
86 testPassed("Exceeded SNR threshold of " + thresholdSNR + " dB"); | |
87 } | |
88 | |
89 if (maxError > thresholdDiff) { | |
90 testFailed("Maximum difference of " + (maxError * waveScaleFacto
r) + " at " | |
91 + errorPosition + " exceeded threshold of " + (thresholdDiff
* waveScaleFactor) | |
92 + " ulp (16-bits)"); | |
93 } else { | |
94 testPassed("Maximum difference below threshold of " | |
95 + (thresholdDiff * waveScaleFactor) + " ulp (16-bits)"); | |
96 } | |
97 if (diffCount > thresholdDiffCount) { | |
98 testFailed(diffCount + " differences found but expected no more
than " + thresholdDiffCount); | |
99 } else { | |
100 testPassed("Number of differences between actual and expected re
sult is less than " + thresholdDiffCount); | |
101 } | |
102 | |
103 finishJSTest(); | |
104 } | |
105 | |
106 function finishedLoading(bufferList) { | |
107 reference = bufferList[0].getChannelData(0); | |
108 generateExponentialOscillatorSweep(context, "sine"); | |
109 context.oncomplete = checkResult; | |
110 context.startRendering(); | |
111 } | |
112 | |
113 function runTest () { | |
114 window.jsTestIsAsync = true; | |
115 | |
116 // Create offline audio context. | |
117 context = new OfflineAudioContext(1, sampleRate * lengthInSeconds, s
ampleRate); | |
118 | |
119 bufferLoader = new BufferLoader( | |
120 context, | |
121 [ "oscillator-sine-expected.wav" ], | |
122 finishedLoading); | |
123 | |
124 bufferLoader.load(); | |
125 } | |
126 | |
127 runTest(); | |
128 successfullyParsed = true; | |
129 </script> | 21 </script> |
130 </body> | 22 </body> |
131 </html> | 23 </html> |
OLD | NEW |