OLD | NEW |
(Empty) | |
| 1 <!doctype html> |
| 2 <html> |
| 3 <head> |
| 4 <title>Test Oscillator Node: sine</title> |
| 5 <script src="resources/compatibility.js"></script> |
| 6 <script src="resources/buffer-loader.js"></script> |
| 7 <script src="../resources/js-test.js"></script> |
| 8 <script src="resources/oscillator-testing.js"></script> |
| 9 </head> |
| 10 |
| 11 <body> |
| 12 <script> |
| 13 // See oscillator-sine.html for more info on the actual wave shape. |
| 14 // |
| 15 // This test is a partial duplicate of oscillator-sine but is designed t
o be less sensitive |
| 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 |
| 21 var sampleRate = 44100.0; |
| 22 var nyquist = 0.5 * sampleRate; |
| 23 var lengthInSeconds = 4; |
| 24 var lowFrequency = 10; |
| 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> |
| 130 </body> |
| 131 </html> |
OLD | NEW |