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