| <!doctype html> |
| <html> |
| <head> |
| <title> |
| Test Reconnection of Tail-Processing Nodes |
| </title> |
| <script src="../../imported/w3c/web-platform-tests/resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script src="../resources/audit.js"></script> |
| <script src="../resources/audit-util.js"></script> |
| </head> |
| |
| <body> |
| <script> |
| let audit = Audit.createTaskRunner(); |
| |
| audit.define( |
| { |
| test: 'Test Compressor', |
| label: 'Reconnect graph to DynamicsCompressor before end of tail' |
| }, |
| (task, should) => { |
| // Arbitrary sample rate |
| const sampleRate = 16000; |
| |
| // These constants taken from dyanmics_compress_kernel.{cc,h}. |
| const preDelayFrames = 1024; |
| const meteringReleaseTime = 0.325; |
| const tailTime = 5 * meteringReleaseTime; |
| const latencyTime = preDelayFrames / sampleRate; |
| const tailProcessingTime = tailTime + latencyTime; |
| |
| // The DynamicsCompressorNode has a tail + latency time of a little |
| // over 1.68 sec, so make the duration longer than that. |
| const renderDuration = 3; |
| |
| let context = new OfflineAudioContext( |
| 1, renderDuration * sampleRate, sampleRate); |
| |
| |
| runTest(context, should, { |
| testNodeName: 'DynamicsCompressorNode', |
| nodeOptions: null, |
| suspendTime: 2, |
| tailProcessingTime: tailProcessingTime |
| }).then(() => task.done()); |
| }); |
| |
| audit.define( |
| { |
| test: 'Test Biquad', |
| label: 'Reconnect graph to Biquad before end of tail' |
| }, |
| (task, should) => { |
| let renderDuration = 1; |
| let sampleRate = 16384; |
| |
| let context = new OfflineAudioContext( |
| 1, renderDuration * sampleRate, sampleRate); |
| |
| // Taken from BiquadFilter/tail-time-lowpass.html |
| let filterOptions = { |
| type: 'lowpass', |
| Q: 40, |
| frequency: sampleRate / 4 |
| }; |
| let tailProcessingTime = 2079.4 / context.sampleRate; |
| |
| runTest(context, should, { |
| testNodeName: 'BiquadFilterNode', |
| nodeOptions: filterOptions, |
| suspendTime: .5, |
| tailProcessingTime: tailProcessingTime |
| }).then(() => task.done()); |
| |
| }); |
| |
| // Run a test using the given test node that has a tail time. |
| // |options| is a dictionary with the following members: |
| // testNodeName: name of the node (used as a constructor) |
| // nodeOptiosn: any options needed to create the node with the right |
| // properties. |
| // suspendTime: Time at which oscillator should start. |
| // tailProcessingTime: Length of the tail of the node, in sec. |
| function runTest(context, should, options) { |
| // This test basically taken from the repro case in crbug.com/829767 |
| let osc = new OscillatorNode(context); |
| let g0 = new GainNode(context); |
| let g1 = new GainNode(context); |
| let g2 = new GainNode(context); |
| let g3 = new GainNode(context); |
| let testNode = |
| new window[options.testNodeName](context, options.nodeOptions); |
| |
| osc.connect(g0) |
| .connect(g1) |
| .connect(testNode) |
| .connect(g2) |
| .connect(g3) |
| .connect(context.destination); |
| |
| // Disconnect the rest of the graph from g0. This should place the |
| // test node on the internal tail processing list. |
| g0.disconnect(); |
| // Now reconnect g0 to the graph.. This should re-enable the test node |
| // output and remove it from the tail list. |
| g0.connect(g1); |
| |
| // Start the source after the tail time of the test node. |
| context.suspend(options.suspendTime) |
| .then(() => { |
| // Sanity check that we start the oscillator after the tail |
| // processing time. |
| should(context.currentTime, 'Oscillator start time') |
| .beGreaterThanOrEqualTo(options.tailProcessingTime); |
| osc.start(); |
| }) |
| .then(() => context.resume()); |
| |
| return context.startRendering().then(renderedBuffer => { |
| // Just check that the output isn't silence. If things are working |
| // after reconnecting, there should be non-zero output. |
| should( |
| renderedBuffer.getChannelData(0), |
| `Output of ${options.testNodeName}`) |
| .notBeConstantValueOf(0); |
| }); |
| } |
| |
| audit.run(); |
| </script> |
| </body> |
| </html> |