OLD | NEW |
1 <!doctype html> | 1 <!DOCTYPE html> |
2 <html> | 2 <html> |
3 <head> | 3 <head> |
4 <title>Test fftSize Changes Resetting AnalyserNode State </title> | 4 <title> |
| 5 Test fftSize Changes Resetting AnalyserNode State |
| 6 </title> |
5 <script src="../../resources/testharness.js"></script> | 7 <script src="../../resources/testharness.js"></script> |
6 <script src="../../resources/testharnessreport.js"></script> | 8 <script src="../../resources/testharnessreport.js"></script> |
7 <script src="../resources/audit-util.js"></script> | 9 <script src="../resources/audit-util.js"></script> |
8 <script src="../resources/audit.js"></script> | 10 <script src="../resources/audit.js"></script> |
9 </head> | 11 </head> |
| 12 <body> |
| 13 <script id="layout-test-code"> |
| 14 // Fairly arbitrary sample rate. |
| 15 let sampleRate = 24000; |
10 | 16 |
11 <body> | 17 let audit = Audit.createTaskRunner(); |
12 <script> | |
13 // Fairly arbitrary sample rate. | |
14 var sampleRate = 24000; | |
15 | |
16 var audit = Audit.createTaskRunner(); | |
17 | 18 |
18 // Verify that setting the fftSize resets the memory for the FFT smoothing | 19 // Verify that setting the fftSize resets the memory for the FFT smoothing |
19 // operation. Only a few of the possible variations are tested. | 20 // operation. Only a few of the possible variations are tested. |
20 | 21 |
21 audit.define("128->1024", (task, should) => { | 22 audit.define('128->1024', (task, should) => { |
22 testFFTSize(should, { | 23 testFFTSize(should, { |
23 initialFFTSize: 128, | 24 initialFFTSize: 128, |
24 finalFFTSize: 1024, | 25 finalFFTSize: 1024, |
25 errorThreshold: { | 26 errorThreshold: {relativeThreshold: 1.9095e-6} |
26 relativeThreshold: 1.9095e-6 | |
27 } | |
28 }).then(() => task.done()); | 27 }).then(() => task.done()); |
29 }); | 28 }); |
30 | 29 |
31 audit.define("512->256", (task, should) => { | 30 audit.define('512->256', (task, should) => { |
32 testFFTSize(should, { | 31 testFFTSize(should, { |
33 initialFFTSize: 512, | 32 initialFFTSize: 512, |
34 finalFFTSize: 256, | 33 finalFFTSize: 256, |
35 errorThreshold: { | 34 errorThreshold: {relativeThreshold: 1.8166e-6} |
36 relativeThreshold: 1.8166e-6 | |
37 } | |
38 }).then(() => task.done()); | 35 }).then(() => task.done()); |
39 }); | 36 }); |
40 | 37 |
41 function testFFTSize(should, options) { | 38 function testFFTSize(should, options) { |
42 var { | 39 let {initialFFTSize, finalFFTSize, errorThreshold} = options; |
43 initialFFTSize, finalFFTSize, errorThreshold | |
44 } = options; | |
45 | 40 |
46 // The duration is fairly arbitrary as long as it's long enough for the | 41 // The duration is fairly arbitrary as long as it's long enough for the |
47 // FFT test. | 42 // FFT test. |
48 var context = new OfflineAudioContext(1, sampleRate, sampleRate); | 43 let context = new OfflineAudioContext(1, sampleRate, sampleRate); |
49 | 44 |
50 // Actual source doesn't matter but a sawtooth is a nice waveform with | 45 // Actual source doesn't matter but a sawtooth is a nice waveform with |
51 // lots of harmonic content. | 46 // lots of harmonic content. |
52 var osc = context.createOscillator(); | 47 let osc = context.createOscillator(); |
53 osc.type = "sawtooth"; | 48 osc.type = 'sawtooth'; |
54 | 49 |
55 // The analyser under test. | 50 // The analyser under test. |
56 var testAnalyser = context.createAnalyser(); | 51 let testAnalyser = context.createAnalyser(); |
57 testAnalyser.fftSize = initialFFTSize; | 52 testAnalyser.fftSize = initialFFTSize; |
58 | 53 |
59 // The reference analyser. The fftSize is fixed to the desired value, | 54 // The reference analyser. The fftSize is fixed to the desired value, |
60 // and we turn off smoothing so that we get the FFT of the current time | 55 // and we turn off smoothing so that we get the FFT of the current time |
61 // data. | 56 // data. |
62 var refAnalyser = context.createAnalyser(); | 57 let refAnalyser = context.createAnalyser(); |
63 refAnalyser.fftSize = finalFFTSize; | 58 refAnalyser.fftSize = finalFFTSize; |
64 refAnalyser.smoothingTimeConstant = 0; | 59 refAnalyser.smoothingTimeConstant = 0; |
65 | 60 |
66 // Setup the graph and start the oscillator. | 61 // Setup the graph and start the oscillator. |
67 osc.connect(testAnalyser) | 62 osc.connect(testAnalyser).connect(context.destination); |
68 .connect(context.destination); | 63 osc.connect(refAnalyser).connect(context.destination); |
69 osc.connect(refAnalyser) | |
70 .connect(context.destination); | |
71 | 64 |
72 osc.start(); | 65 osc.start(); |
73 | 66 |
74 // Let the analyser smooth a few FFTs (rather arbitrary, but should be | 67 // Let the analyser smooth a few FFTs (rather arbitrary, but should be |
75 // more than one), then switch the size. | 68 // more than one), then switch the size. |
76 | 69 |
77 var suspendFrame = 4 * initialFFTSize; | 70 let suspendFrame = 4 * initialFFTSize; |
78 context.suspend(suspendFrame / context.sampleRate) | 71 context.suspend(suspendFrame / context.sampleRate) |
79 .then(function () { | 72 .then(function() { |
80 testAnalyser.fftSize = finalFFTSize; | 73 testAnalyser.fftSize = finalFFTSize; |
81 }) | 74 }) |
82 .then(context.resume.bind(context)); | 75 .then(context.resume.bind(context)); |
83 | 76 |
84 // Wait some frames and grab the FFT data. This is fairly arbitrary | 77 // Wait some frames and grab the FFT data. This is fairly arbitrary |
85 // too, and can be independent of the FFT sizes. | 78 // too, and can be independent of the FFT sizes. |
86 suspendFrame += 1024; | 79 suspendFrame += 1024; |
87 context.suspend(suspendFrame / context.sampleRate) | 80 context.suspend(suspendFrame / context.sampleRate) |
88 .then(function () { | 81 .then(function() { |
89 var testFFT = new Float32Array(testAnalyser.frequencyBinCount); | 82 let testFFT = new Float32Array(testAnalyser.frequencyBinCount); |
90 var refFFT = new Float32Array(refAnalyser.frequencyBinCount) | 83 let refFFT = new Float32Array(refAnalyser.frequencyBinCount) |
91 var testSignal = new Float32Array(testAnalyser.fftSize); | 84 let testSignal = new Float32Array(testAnalyser.fftSize); |
92 var refSignal = new Float32Array(refAnalyser.fftSize); | 85 let refSignal = new Float32Array(refAnalyser.fftSize); |
93 | 86 |
94 testAnalyser.getFloatTimeDomainData(testSignal); | 87 testAnalyser.getFloatTimeDomainData(testSignal); |
95 refAnalyser.getFloatTimeDomainData(refSignal); | 88 refAnalyser.getFloatTimeDomainData(refSignal); |
96 | 89 |
97 testAnalyser.getFloatFrequencyData(testFFT); | 90 testAnalyser.getFloatFrequencyData(testFFT); |
98 refAnalyser.getFloatFrequencyData(refFFT); | 91 refAnalyser.getFloatFrequencyData(refFFT); |
99 | 92 |
100 // Convert the FFT data from dB to linear | 93 // Convert the FFT data from dB to linear |
101 testFFT = testFFT.map(x => Math.pow(10, x / 20)); | 94 testFFT = testFFT.map(x => Math.pow(10, x / 20)); |
102 refFFT = refFFT.map(x => Math.pow(10, x / 20)); | 95 refFFT = refFFT.map(x => Math.pow(10, x / 20)); |
103 | 96 |
104 // The test data has smoothing applied, but the reference doesn't. | 97 // The test data has smoothing applied, but the reference doesn't. |
105 // Apply the smoothing factor to the reference data. | 98 // Apply the smoothing factor to the reference data. |
106 var smoothing = 1 - testAnalyser.smoothingTimeConstant; | 99 let smoothing = 1 - testAnalyser.smoothingTimeConstant; |
107 refFFT = refFFT.map(x => x * smoothing); | 100 refFFT = refFFT.map(x => x * smoothing); |
108 | 101 |
109 // First a basic sanity check that the time domain signals are | 102 // First a basic sanity check that the time domain signals are |
110 // exactly the same for both analysers. | 103 // exactly the same for both analysers. |
111 should(testSignal, "Time data") | 104 should(testSignal, 'Time data').beCloseToArray(refSignal, 0); |
112 .beCloseToArray(refSignal, 0); | |
113 | 105 |
114 should(testFFT, "Linear FFT data after setting fftSize = " + testAna
lyser.fftSize) | 106 should( |
115 .beCloseToArray(refFFT, errorThreshold); | 107 testFFT, |
116 }) | 108 'Linear FFT data after setting fftSize = ' + |
117 .then(context.resume.bind(context)); | 109 testAnalyser.fftSize) |
| 110 .beCloseToArray(refFFT, errorThreshold); |
| 111 }) |
| 112 .then(context.resume.bind(context)); |
118 | 113 |
119 return context.startRendering(); | 114 return context.startRendering(); |
120 } | 115 } |
121 | 116 |
122 audit.run(); | 117 audit.run(); |
123 </script> | 118 </script> |
124 </body> | 119 </body> |
125 </html> | 120 </html> |
OLD | NEW |