OLD | NEW |
| (Empty) |
1 <!doctype html> | |
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 <script src="resources/realtimeanalyser-testing.js"></script> | |
9 <script src="resources/fft.js"></script> | |
10 <title>Test Analyser getFloatFrequencyData and getByteFrequencyData, Smoothi
ng</title> | |
11 | |
12 </head> | |
13 | |
14 <body> | |
15 <script> | |
16 description("Test AnalyserNode getFloatFrequencyData and getByteFrequencyD
ata, Smoothing"); | |
17 window.jsTestIsAsync = true; | |
18 | |
19 // Use a power of two to eliminate any round-off in the computation of the
times for | |
20 // context.suspend(). | |
21 var sampleRate = 32768; | |
22 | |
23 // The largest FFT size for the analyser node is 32768. We want to render
longer than this so | |
24 // that we have at least one complete buffer of data of 32768 samples. | |
25 var renderFrames = 2 * 32768; | |
26 var renderDuration = renderFrames / sampleRate; | |
27 | |
28 var audit = Audit.createTaskRunner(); | |
29 | |
30 // Do one basic test of smoothing of the FFT data. | |
31 audit.defineTask("smoothing test", function (done) { | |
32 // Test only 512-point FFT. The size isn't too important as long as it'
s greater than 128 | |
33 // (a rendering quantum). | |
34 var options = { | |
35 order: 9, | |
36 smoothing: 0.5, | |
37 floatRelError: 5.9207e-6 | |
38 }; | |
39 | |
40 var success = true; | |
41 | |
42 var graph = createGraph(options); | |
43 | |
44 context = graph.context; | |
45 analyser = graph.analyser; | |
46 | |
47 var smoothedFloatResult = new Float32Array(analyser.frequencyBinCount); | |
48 smoothedFloatResult.fill(0); | |
49 | |
50 // Stop after one analyser frame to get the initial FFT | |
51 var suspendFrame = analyser.fftSize; | |
52 context.suspend(suspendFrame / sampleRate).then(function () { | |
53 var timeData = new Float32Array(analyser.fftSize); | |
54 var freqData = new Float32Array(analyser.frequencyBinCount); | |
55 analyser.getFloatTimeDomainData(timeData); | |
56 analyser.getFloatFrequencyData(freqData); | |
57 | |
58 var expectedFreq = computeFFTMagnitude(timeData, options.order); | |
59 smoothFFT(smoothedFloatResult, expectedFreq, options.smoothing); | |
60 | |
61 var message = "First " + analyser.fftSize + "-point FFT at frame " + (
context.currentTime * | |
62 sampleRate); | |
63 var comparison = compareFloatFreq(message, freqData, smoothedFloatResu
lt.map( | |
64 linearToDb), options); | |
65 success = success && comparison.success; | |
66 | |
67 // Test the byte frequency data. | |
68 var byteFreqData = new Uint8Array(analyser.frequencyBinCount); | |
69 var expectedByteData = new Float32Array(analyser.frequencyBinCount); | |
70 analyser.getByteFrequencyData(byteFreqData); | |
71 | |
72 // Convert the expected float frequency data to byte data. | |
73 var expectedByteData = convertFloatToByte(smoothedFloatResult.map(line
arToDb), | |
74 analyser.minDecibels, analyser.maxDecibels); | |
75 | |
76 success = Should(analyser.fftSize + "-point byte FFT", byteFreqData) | |
77 .beCloseToArray(expectedByteData, 0) && success; | |
78 | |
79 }).then(context.resume.bind(context)); | |
80 | |
81 // Skip an analyser frame and grab another to verify that the smoothing
is done correctly. | |
82 suspendFrame += 2 * analyser.fftSize; | |
83 context.suspend(suspendFrame / sampleRate).then(function () { | |
84 var timeData = new Float32Array(analyser.fftSize); | |
85 var freqDataInDb = new Float32Array(analyser.frequencyBinCount); | |
86 | |
87 // Grab the time domain and frequency domain data | |
88 analyser.getFloatTimeDomainData(timeData); | |
89 analyser.getFloatFrequencyData(freqDataInDb); | |
90 | |
91 var newFreqData = computeFFTMagnitude(timeData, options.order); | |
92 // Smooth the data together | |
93 | |
94 smoothFFT(smoothedFloatResult, newFreqData, options.smoothing); | |
95 var message = "Smoothed " + analyser.fftSize + "-point FFT at frame "
+ | |
96 (context.currentTime * sampleRate); | |
97 var comparison = compareFloatFreq(message, | |
98 freqDataInDb, smoothedFloatResult.map(linearToDb), { | |
99 order: options.order, | |
100 smoothing: options.smoothing, | |
101 floatRelError: 2.5332e-5 | |
102 }); | |
103 success = success && comparison.success; | |
104 | |
105 // Test the byte frequency data. | |
106 var byteFreqData = new Uint8Array(analyser.frequencyBinCount); | |
107 var expectedByteData = new Float32Array(analyser.frequencyBinCount); | |
108 analyser.getByteFrequencyData(byteFreqData); | |
109 | |
110 // Convert the expected float frequency data to byte data. | |
111 var expectedByteData = convertFloatToByte(smoothedFloatResult.map(line
arToDb), | |
112 analyser.minDecibels, analyser.maxDecibels); | |
113 | |
114 success = Should(analyser.fftSize + "-point byte FFT", byteFreqData) | |
115 .beCloseToArray(expectedByteData, 0) && success; | |
116 | |
117 }).then(context.resume.bind(context)); | |
118 | |
119 context.startRendering().then(function (buffer) { | |
120 var prefix = "FFT smoothing performed "; | |
121 var suffix = " with smoothing constant " + analyser.smoothingTimeConst
ant + ".\n" | |
122 | |
123 if (success) | |
124 testPassed(prefix + "correctly" + suffix); | |
125 else | |
126 testFailed(prefix + "incorrectly" + suffix); | |
127 }).then(done); | |
128 }); | |
129 | |
130 audit.defineTask("finish", function (done) { | |
131 finishJSTest(); | |
132 done(); | |
133 }); | |
134 | |
135 audit.runTasks(); | |
136 | |
137 </script> | |
138 </body> | |
139 </html> | |
OLD | NEW |