| 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 |