| <!DOCTYPE html> |
| <html> |
| <head> |
| <title> |
| Test Multiple Calls to getFloatFrequencyData |
| </title> |
| <script src="../../imported/w3c/web-platform-tests/resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script src="../resources/audit-util.js"></script> |
| <script src="../resources/audit.js"></script> |
| </head> |
| <body> |
| <script id="layout-test-code"> |
| let sampleRate = 48000; |
| // Render enough data to run the test. |
| let renderFrames = 2 * 1024; |
| let renderDuration = renderFrames / sampleRate; |
| |
| let audit = Audit.createTaskRunner(); |
| |
| audit.define('test', (task, should) => { |
| |
| let context = new OfflineAudioContext(1, renderFrames, sampleRate); |
| |
| // Use sawtooth oscillator as the source because it has quite a bit of |
| // harmonic content. Otherwise, the type doesn't really matter. |
| let osc = context.createOscillator(); |
| osc.type = 'sawtooth'; |
| |
| // Create an analyser with 256-point FFT. The FFT size doesn't really |
| // matter much. |
| let analyser = context.createAnalyser(); |
| analyser.fftSize = 256; |
| |
| osc.connect(analyser); |
| analyser.connect(context.destination); |
| |
| let success = true; |
| |
| // Suspend after getting a full analyser frame. (Not really necessary, |
| // but it's nice that the frame doesn't include any initial zeroes. |
| let suspendFrame = analyser.fftSize; |
| context.suspend(suspendFrame / sampleRate) |
| .then(function() { |
| // Test successive calls to getFloatFrequencyData in the same |
| // rendering quantum. |
| let f1 = new Float32Array(analyser.frequencyBinCount); |
| let f2 = new Float32Array(analyser.frequencyBinCount); |
| |
| analyser.getFloatFrequencyData(f1); |
| analyser.getFloatFrequencyData(f2); |
| should(f2, 'Second call to getFloatFrequencyData') |
| .beEqualToArray(f1); |
| }) |
| .then(context.resume.bind(context)); |
| |
| suspendFrame += 128; |
| context.suspend(suspendFrame / sampleRate) |
| .then(function() { |
| // Test successive calls to getByteFrequencyData in the same |
| // rendering quantum. |
| let f1 = new Uint8Array(analyser.frequencyBinCount); |
| let f2 = new Uint8Array(analyser.frequencyBinCount); |
| |
| analyser.getByteFrequencyData(f1); |
| analyser.getByteFrequencyData(f2); |
| |
| should(f2, 'Second call to getByteFrequencyData') |
| .beEqualToArray(f1); |
| }) |
| .then(context.resume.bind(context)); |
| |
| suspendFrame += 128; |
| context.suspend(suspendFrame / sampleRate) |
| .then(function() { |
| // Test calls to getFloatFrequencyData followed by |
| // getByteFrequencyData. The float data, when converted to byte |
| // values should be identical to the result from |
| // getByteFrequencyData. |
| let f1 = new Float32Array(analyser.frequencyBinCount); |
| let f2 = new Uint8Array(analyser.frequencyBinCount); |
| |
| analyser.getFloatFrequencyData(f1); |
| analyser.getByteFrequencyData(f2); |
| |
| let byteValuesFromFloat = convertFloatToByte( |
| f1, analyser.minDecibels, analyser.maxDecibels); |
| should( |
| byteValuesFromFloat, |
| 'Output of getByteFrequencyData after getFloatFrequencyData') |
| .beEqualToArray(f2); |
| }) |
| .then(context.resume.bind(context)); |
| |
| suspendFrame += 128; |
| context.suspend(suspendFrame / sampleRate) |
| .then(function() { |
| // Test calls to getByteFrequencyData followed by |
| // getFloatFrequencyData. The float data, when converted to byte |
| // values should be identical to the result from |
| // getByteFrequencyData. |
| let f1 = new Uint8Array(analyser.frequencyBinCount); |
| let f2 = new Float32Array(analyser.frequencyBinCount); |
| |
| analyser.getByteFrequencyData(f1); |
| analyser.getFloatFrequencyData(f2); |
| |
| let byteValuesFromFloat = convertFloatToByte( |
| f2, analyser.minDecibels, analyser.maxDecibels); |
| should( |
| f1, |
| 'Output of getFloatFrequenycData (converted to byte) after getByteFrequencyData') |
| .beEqualToArray(byteValuesFromFloat); |
| }) |
| .then(context.resume.bind(context)); |
| |
| osc.start(); |
| context.startRendering().then(() => task.done()); |
| }); |
| |
| audit.run(); |
| |
| // Convert the float frequency data (in dB), |floatFreqData|, to byte |
| // values using the dB limits |minDecibels| and |maxDecibels|. The new |
| // byte array is returned. |
| function convertFloatToByte(floatFreqData, minDecibels, maxDecibels) { |
| let scale = 255 / (maxDecibels - minDecibels); |
| |
| return floatFreqData.map(function(x) { |
| let value = Math.floor(scale * (x - minDecibels)); |
| return Math.min(255, Math.max(0, value)); |
| }); |
| } |
| </script> |
| </body> |
| </html> |