Refactoring: Pull all fullscreen code out of Document and into its own helper class
[WebKit-https.git] / LayoutTests / webaudio / realtimeanalyser-fft-scaling.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html>
3   <head>
4     <script src="../resources/js-test.js"></script>
5     <script src="resources/audio-testing.js"></script>
6   </head>
7
8   <body>
9     <div id="description"></div>
10     <div id="console"></div>
11
12     <script>
13 description("Test scaling of FFT data for AnalyserNode");
14
15 // The number of analysers. We have analysers from size for each of the possible sizes of 32,
16 // 64, 128, 256, 512, 1024 and 2048.
17 var numberOfAnalysers = 7;
18 var sampleRate = 44100;
19 var context;
20 var osc;
21 var oscFrequency = sampleRate/32;
22 var analysers = new Array(7);
23 var peakValue = new Array(7);
24
25 // For a 0dBFS sine wave, we would expect the FFT magnitude to be 0dB as well, but the
26 // analyzer node applies a Blackman window (to smooth the estimate).  This reduces the energy
27 // of the signal so the FFT peak is less than 0dB.  The threshold value given here was
28 // determined experimentally.
29 //
30 // See https://code.google.com/p/chromium/issues/detail?id=341596.
31 var peakThreshold = [-8.41, -7.54, -7.54, -7.54, -7.54, -7.54, -7.54];
32
33 function checkResult() {
34     var allTestsPassed = true;
35
36     for (var n = 0; n < analysers.length; ++n) {
37         // Grab the FFT data from each analyser.
38         var fftSize = analysers[n].fftSize;
39         var fftData = new Float32Array(fftSize);
40         analysers[n].getFloatFrequencyData(fftData);
41
42         // Compute the frequency bin that should contain the peak.
43         var expectedBin = fftSize * (oscFrequency / sampleRate);
44
45         // Find the actual bin by finding the bin containing the peak.
46         var actualBin = 0;
47         peakValue[n] = -1000;
48         for (k = 0; k < analysers[n].frequencyBinCount; ++k) {
49             if (fftData[k] > peakValue[n]) {
50                 actualBin = k;
51                 peakValue[n] = fftData[k];
52             }
53         }
54
55         var success = true;
56
57         if (actualBin == expectedBin) {
58             testPassed("Actual FFT peak in the expected position (" + expectedBin + ")");
59         } else {
60             success = false;
61             testFailed("Actual FFT peak (" + actualBin + ") differs from expected (" + expectedBin + ")");
62         }
63
64         if (peakValue[n] >= peakThreshold[n]) {
65             testPassed("Peak value is near 0 dBFS as expected");
66         } else {
67             success = false;
68             testFailed("Peak value of " + peakValue[n]
69             + " is incorrect.  (Expected approximately "
70             + peakThreshold[n] + ")");
71         }
72
73         if (success) {
74             testPassed("Analyser correctly scaled FFT data of size " + fftSize);
75         } else {
76             testFailed("Analyser incorrectly scaled FFT data of size " + fftSize);
77         }
78         allTestsPassed = allTestsPassed && success;
79     }
80
81     if (allTestsPassed) {
82         testPassed("All Analyser tests passed.");
83     } else {
84         testFailed("At least one Analyser test failed.");
85     }
86
87     finishJSTest();
88 }
89
90 function runTests() {
91     window.jsTestIsAsync = true;
92
93     context = new webkitOfflineAudioContext(1, 2048, sampleRate);
94
95     // Use a sine wave oscillator as the reference source signal.
96     osc = context.createOscillator();
97     osc.type = "sine";
98     osc.frequency.value = oscFrequency;
99     osc.connect(context.destination);
100
101     // Create an analyser node for each of the possible valid sizes.
102     for (var order = 5; order < 12; ++order) {
103         analysers[order - 5] = context.createAnalyser();
104         // No smoothing so between frames to simplify testing.
105         analysers[order - 5].smoothingTimeConstant = 0;
106         analysers[order - 5].fftSize = 1 << order;
107         osc.connect(analysers[order - 5]);
108     }
109
110     osc.start(0);
111     context.oncomplete = checkResult;
112     context.startRendering();
113 }
114
115 runTests();
116     </script>
117   </body>
118 </html>