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