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