Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(531)

Side by Side Diff: LayoutTests/webaudio/realtimeanalyser-fft-scaling.html

Issue 316293002: Make realtimeanalyser-fft-scaling test more robust (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html> 2 <html>
3 <head> 3 <head>
4 <script src="../resources/js-test.js"></script> 4 <script src="../resources/js-test.js"></script>
5 <script src="resources/compatibility.js"></script> 5 <script src="resources/compatibility.js"></script>
6 <script src="resources/audio-testing.js"></script> 6 <script src="resources/audio-testing.js"></script>
7 </head> 7 </head>
8 8
9 <body> 9 <body>
10 <div id="description"></div> 10 <div id="description"></div>
11 <div id="console"></div> 11 <div id="console"></div>
12 12
13 <script> 13 <script>
14 description("Test scaling of FFT data for AnalyserNode"); 14 description("Test scaling of FFT data for AnalyserNode");
15 15
16 // The number of analysers. We have analysers from size for each of the po ssible sizes of 32, 16 // The number of analysers. We have analysers from size for each of the po ssible sizes of 32,
17 // 64, 128, 256, 512, 1024 and 2048. 17 // 64, 128, 256, 512, 1024 and 2048 for a total of 7.
18 var numberOfAnalysers = 7; 18 var numberOfAnalysers = 7;
19 var sampleRate = 44100; 19 var sampleRate = 44100;
20 var context; 20 var nyquistFrequency = sampleRate / 2;
21 var osc; 21
22 var oscFrequency = sampleRate/32; 22 // Frequency of the sine wave test signal. Should be high enough so that we get at least one
23 var analysers = new Array(7); 23 // full cycle for the 32-point FFT. This should also be such that the fre quency should be
24 var peakValue = new Array(7); 24 // exactly in one of the FFT bins for each of the possible FFT sizes.
25 var oscFrequency = nyquistFrequency/16;
26
27 // The actual peak values from each analyser. Useful for examining the re sults in Chrome.
28 var peakValue = new Array(numberOfAnalysers);
25 29
26 // For a 0dBFS sine wave, we would expect the FFT magnitude to be 0dB as w ell, but the 30 // For a 0dBFS sine wave, we would expect the FFT magnitude to be 0dB as w ell, but the
27 // analyzer node applies a Blackman window (to smooth the estimate). This reduces the energy 31 // analyzer node applies a Blackman window (to smooth the estimate). This reduces the energy
28 // of the signal so the FFT peak is less than 0dB. The threshold value gi ven here was 32 // of the signal so the FFT peak is less than 0dB. The threshold value gi ven here was
29 // determined experimentally. 33 // determined experimentally.
30 // 34 //
31 // See https://code.google.com/p/chromium/issues/detail?id=341596. 35 // See https://code.google.com/p/chromium/issues/detail?id=341596.
32 var peakThreshold = [-14.43, -13.56, -13.56, -13.56, -13.56, -13.56, -13.5 6]; 36 var peakThreshold = [-14.43, -13.56, -13.56, -13.56, -13.56, -13.56, -13.5 6];
33 37
34 function checkResult() { 38 var allTestsPassed = true;
35 » var allTestsPassed = true;
36 39
37 » for (n = 0; n < analysers.length; ++n) { 40 function checkResult(order, analyser) {
38 » // Grab the FFT data from each analyser. 41 return function () {
39 » var fftSize = analysers[n].fftSize; 42 var index = order - 5;
40 » var fftData = new Float32Array(fftSize); 43 var fftSize = 1 << order;
41 » analysers[n].getFloatFrequencyData(fftData); 44 var fftData = new Float32Array(fftSize);
45 analyser.getFloatFrequencyData(fftData);
42 46
43 » // Compute the frequency bin that should contain the peak. 47 // Compute the frequency bin that should contain the peak.
44 » var expectedBin = fftSize * (oscFrequency / sampleRate); 48 var expectedBin = analyser.frequencyBinCount * (oscFrequency / nyq uistFrequency);
45 49
46 » // Find the actual bin by finding the bin containing the peak. 50 // Find the actual bin by finding the bin containing the peak.
47 » var actualBin = 0; 51 var actualBin = 0;
48 » peakValue[n] = -1000; 52 peakValue[index] = -1000;
49 » for (k = 0; k < analysers[n].frequencyBinCount; ++k) { 53 for (k = 0; k < analyser.frequencyBinCount; ++k) {
50 » » if (fftData[k] > peakValue[n]) { 54 if (fftData[k] > peakValue[index]) {
51 » » actualBin = k; 55 actualBin = k;
52 » » peakValue[n] = fftData[k]; 56 peakValue[index] = fftData[k];
53 » » } 57 }
54 » } 58 }
55 59
56 » var success = true; 60 var success = true;
57 61
58 » if (actualBin == expectedBin) { 62 if (actualBin == expectedBin) {
59 » » testPassed("Actual FFT peak in the expected position (" + expe ctedBin + ")"); 63 testPassed("Actual FFT peak in the expected position (" + expe ctedBin + ").");
60 » } else { 64 } else {
61 » » success = false; 65 success = false;
62 » » testFailed("Actual FFT peak (" + actualBin + ") differs from e xpected (" + expectedBin + ")"); 66 testFailed("Actual FFT peak (" + actualBin + ") differs from e xpected (" + expectedBin + ").");
63 » } 67 }
64 68
65 » if (peakValue[n] >= peakThreshold[n]) { 69 if (peakValue[index] >= peakThreshold[index]) {
66 » » testPassed("Peak value is near 0 dBFS as expected"); 70 testPassed("Peak value is near " + peakThreshold[index] + " dB FS as expected.");
67 » } else { 71 } else {
68 » » success = false; 72 success = false;
69 » » testFailed("Peak value of " + peakValue[n] 73 testFailed("Peak value of " + peakValue[index]
70 + " is incorrect. (Expected approximately " 74 + " is incorrect. (Expected approximately "
71 + peakThreshold[n] + ")"); 75 + peakThreshold[index] + ").");
72 » } 76 }
73 77
74 » if (success) { 78 if (success) {
75 » » testPassed("Analyser correctly scaled FFT data of size " + fft Size); 79 testPassed("Analyser correctly scaled FFT data of size " + fft Size);
76 » } else { 80 } else {
77 » » testFailed("Analyser incorrectly scaled FFT data of size " + f ftSize); 81 testFailed("Analyser incorrectly scaled FFT data of size " + f ftSize);
78 » } 82 }
79 » allTestsPassed = allTestsPassed && success; 83 allTestsPassed = allTestsPassed && success;
80 » }
81 84
82 » if (allTestsPassed) { 85 if (fftSize == 2048) {
83 » testPassed("All Analyser tests passed."); 86 if (allTestsPassed) {
84 » } else { 87 testPassed("All Analyser tests passed.");
85 » testFailed("At least one Analyser test failed."); 88 } else {
86 » } 89 testFailed("At least one Analyser test failed.");
90 }
87 91
88 » finishJSTest(); 92 finishJSTest();
93 }
94 }
89 } 95 }
90 96
91 function runTests() { 97 function runTests() {
92 if (window.testRunner) { 98 if (window.testRunner) {
93 testRunner.dumpAsText(); 99 testRunner.dumpAsText();
94 testRunner.waitUntilDone(); 100 testRunner.waitUntilDone();
95 } 101 }
96 102
97 window.jsTestIsAsync = true; 103 window.jsTestIsAsync = true;
98 104
99 context = new OfflineAudioContext(1, 2048, sampleRate); 105 // Test each analyser size from order 5 (size 32) to 11 (size 2048).
106 for (order = 5; order < 12; ++order) {
107 // Create a new offline context for each analyser test with the nu mber of samples
108 // exactly equal to the fft size. This ensures that the analyser node gets the
109 // expected data from the oscillator.
110 var context = new OfflineAudioContext(1, 1 << order, sampleRate);
111 // Use a sine wave oscillator as the reference source signal.
112 var osc = context.createOscillator();
113 osc.type = "sine";
114 osc.frequency.value = oscFrequency;
115 osc.connect(context.destination);
100 116
101 // Use a sine wave oscillator as the reference source signal. 117 var analyser = context.createAnalyser();
102 osc = context.createOscillator(); 118 // No smoothing to simplify the analysis of the result.
103 osc.type = "sine"; 119 analyser.smoothingTimeConstant = 0;
104 osc.frequency.value = oscFrequency; 120 analyser.fftSize = 1 << order;
105 osc.connect(context.destination); 121 osc.connect(analyser);
106 122
107 // Create an analyser node for each of the possible valid sizes. 123 osc.start();
108 for (order = 5; order < 12; ++order) { 124 context.oncomplete = checkResult(order, analyser);
109 » analysers[order - 5] = context.createAnalyser(); 125 context.startRendering();
110 // No smoothing so between frames to simplify testing.
111 » analysers[order - 5].smoothingTimeConstant = 0;
112 » analysers[order - 5].fftSize = 1 << order;
113 osc.connect(analysers[order - 5]);
114 } 126 }
115
116 osc.start();
117 context.oncomplete = checkResult;
118 context.startRendering();
119 } 127 }
120 128
121 runTests(); 129 runTests();
122 successfullyParsed = true; 130 successfullyParsed = true;
123 </script> 131 </script>
124 </body> 132 </body>
125 </html> 133 </html>
OLDNEW
« no previous file with comments | « LayoutTests/TestExpectations ('k') | LayoutTests/webaudio/realtimeanalyser-fft-scaling-expected.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698