Index: third_party/WebKit/LayoutTests/webaudio/Analyser/handle-silent-inputs.html |
diff --git a/third_party/WebKit/LayoutTests/webaudio/Analyser/handle-silent-inputs.html b/third_party/WebKit/LayoutTests/webaudio/Analyser/handle-silent-inputs.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f1db505b74ba9711e717b517006a14f8649fa154 |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/webaudio/Analyser/handle-silent-inputs.html |
@@ -0,0 +1,137 @@ |
+<!doctype html> |
+<html> |
+ <head> |
+ <script src="../../resources/testharness.js"></script> |
+ <script src="../../resources/testharnessreport.js"></script> |
+ <script src="../resources/audit-util.js"></script> |
+ <script src="../resources/audit.js"></script> |
+ <title>Handle Silent Inputs to AnalyserNode</title> |
+ </head> |
+ |
+ <body> |
+ <script> |
+ let audit = Audit.createTaskRunner(); |
+ let sampleRate = 16000; |
+ let renderDuration = 1; |
+ let renderFrames = renderDuration * sampleRate; |
+ |
+ audit.define('connected', function(task, should) { |
+ task.describe('Test handling of silent inputs'); |
+ |
+ tester(should, false).then(task.done.bind(task)); |
+ }); |
+ |
+ audit.define('auto-pull', function(task, should) { |
+ task.describe('Test handling of silent inputs'); |
+ |
+ tester(should, true).then(task.done.bind(task)); |
+ }); |
+ |
+ audit.define('timing', function(task, should) { |
+ task.describe('Test shifting in of zeroes after source has stopped'); |
+ |
+ let renderQuantumFrames = 128; |
+ |
+ // sampleRate chosen to be a power of two so we don't have round-off |
+ // errors in computing the times for when to suspend the context. |
+ let context = new OfflineAudioContext(1, 16384, 16384); |
+ let source = new ConstantSourceNode(context); |
+ |
+ // The fftSize for the analyser is fairly arbitrary, except the code |
+ // assumes it is larger than 128. |
+ let analyser = new AnalyserNode(context, {fftSize: 2048}); |
+ |
+ source.connect(analyser).connect(context.destination); |
+ |
+ source.start(); |
+ |
+ // Stop the source after 1 fftSize frames. |
+ let time = analyser.fftSize / context.sampleRate; |
+ source.stop(time); |
+ |
+ // Verify that the time data at this point is constant. |
+ context.suspend(time) |
+ .then(() => { |
+ let data = new Float32Array(analyser.fftSize); |
+ analyser.getFloatTimeDomainData(data); |
+ should( |
+ data, 'At time ' + context.currentTime + |
+ ' Analyser frames [0, ' + analyser.fftSize + ')') |
+ .beConstantValueOf(1); |
+ }) |
+ .then(context.resume.bind(context)); |
+ |
+ // After each rendering quantum from the point at which the source |
+ // stopped, verify that zeroes are inserted into the time data one |
+ // rendering quantum at a time. |
+ |
+ let limit = analyser.fftSize / renderQuantumFrames; |
+ |
+ for (let k = 1; k <= limit; ++k) { |
+ let analyserTime = |
+ (analyser.fftSize + k * renderQuantumFrames) / context.sampleRate; |
+ context.suspend(analyserTime) |
+ .then(() => { |
+ let data = new Float32Array(analyser.fftSize); |
+ let indexNewest = analyser.fftSize - k * renderQuantumFrames; |
+ analyser.getFloatTimeDomainData(data); |
+ if (k < limit) { |
+ should( |
+ data.slice(0, indexNewest), 'At time ' + |
+ context.currentTime + ' Analyser frames [0, ' + |
+ indexNewest + ')') |
+ .beConstantValueOf(1); |
+ } |
+ should( |
+ data.slice(indexNewest), 'At time ' + context.currentTime + |
+ ' Analyser frames [' + indexNewest + ', ' + |
+ analyser.fftSize + ')') |
+ .beConstantValueOf(0); |
+ }) |
+ .then(context.resume.bind(context)); |
+ } |
+ |
+ // Start the test |
+ context.startRendering().then(() => task.done()); |
+ }); |
+ |
+ audit.run(); |
+ |
+ function tester(should, isAutoPullTest) { |
+ // Connect an oscillator to an analyser for testing the time data of the |
+ // analyser after the oscillator stops. |
+ let context = new OfflineAudioContext(1, renderFrames, sampleRate); |
+ let source = new OscillatorNode(context); |
+ let analyser = new AnalyserNode(context, {fftSize: 128}); |
+ let timeData = new Float32Array(analyser.fftSize); |
+ timeData.fill(NaN); |
+ |
+ source.connect(analyser); |
+ |
+ // For the automatic pull test, leave the analyser output disconnected. |
+ if (isAutoPullTest) { |
+ source.connect(context.destination); |
+ } else { |
+ analyser.connect(context.destination); |
+ } |
+ |
+ source.start(); |
+ |
+ // Stop the source well in advance of when we want to get the time data |
+ // from the analyser. |
+ let stopTime = 0.1; |
+ let dataTime = 0.5; |
+ |
+ source.stop(stopTime); |
+ context.suspend(dataTime) |
+ .then(() => { analyser.getFloatTimeDomainData(timeData); }) |
+ .then(context.resume.bind(context)); |
+ |
+ return context.startRendering().then(buffer => { |
+ should(timeData, 'Analyser time data at time ' + dataTime) |
+ .beConstantValueOf(0); |
+ }); |
+ } |
+ </script> |
+ </body> |
+</html> |