New issue
Advanced search Search tips

Issue 647974 link

Starred by 9 users

Issue metadata

Status: Fixed
Owner:
Closed: Jan 2017
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Bug



Sign in to add a comment

Web Audio Automation

Reported by official...@gmail.com, Sep 17 2016

Issue description

Chrome Version       : 53.0.2785.116 m
URLs (if applicable) : http://howardcshaw.com/chromebug/
Other browsers tested:
  Add OK or FAIL, along with the version, after other browsers where you
have tested this issue:
    Safari: OK unsure which version
    IOS Safari: OK unsure which version
    Firefox: OK 48.0.2
    

What steps will reproduce the problem?
(1) Create an AudioContext, an AudioBufferSourceNode (source) and set its AudioBuffer, and create a GainNode (gain).
(2) Connect the gain to the audio context destination and the source to the gain 
(3) call start on the buffer source and then call stop.
(4) adjust the gain node's gain value using "setValueAtTime" or "linearRampToValueAtTime", possibly the other automation functions.
(5) Recreate your AudioBufferSourceNode, set its AudioBuffer, connect it to the gain, and play it.

    Demo (also linked above): http://howardcshaw.com/chromebug/
    Try muting/unmuting the audio when it is paused, then play again. 


What is the expected result?
    The gain's value should be set to the value specified with your automation call.

What happens instead?
    Using setValueAtTime, the gain's value is unchanged. 
    Using linearRampToValueAtTime, the gain's value is unchanged if the automation event ends before the new source is created and played. If you create and play a new source during the automation, it seems to work fine unless you call stop again and wait until the end of the automation before recreating and starting the source. In this case the gain value remains at whatever it was at when you called stop.


Please provide any additional information below. Attach a screenshot if
possible.
    This happens for other AudioParams as well, not just GainNode.gain

    This was working well in a recent version of Chrome. 
    I'm not sure which or how to check, but it was before 
    the UI update where the menu icon changed from bars to dots.

 
Update: This seems to happen not only when the source is stopped, but also when the audio is made silent. For example, if the source plays continuously and is sent through one gain node which is sent through another gain node and the first gain node's gain value is set to zero, updates to the second gain node's gain value don't have an effect. Sometimes the first few will, but after that no.  
Components: Blink>WebAudio

Comment 3 by rtoy@chromium.org, Sep 19 2016

Status: Available (was: Unconfirmed)
I can confirm the issue. Not sure why it happens, but there have been a lot of changes in the automation code in the last release or two.

Comment 4 by rtoy@chromium.org, Sep 19 2016

I'm a bit confused on your repro steps.  You say try muting/unmuting the audio when it is paused.  Then play again.  What are you expecting to happen here?

Based on your code, independent of the mute/unmute state, the gain node does a linear ramp to 1 at time currentTime + 0.02.  So pressing play will always play some audio.

Please help me understand what is happening for you and how to reproduce it.
There are two gain nodes in the example I posted: "source.node" and "gain"

"source.node" is connected to "gain" and "gain" is the one that mutes the audio. I've updated the example to remove the value changes on "source.node" to hopefully make things clearer. The automations on "source.node" were to declick the audio when playing/pausing before it is passed into "gain". 

This also might be more easily noticed using a biquad filter rather than a gain. If you make any changes to the filter parameters using setValueAtTime or linearRampToValueAtTime that complete when the source has been stopped, the changes do not occur.

Comment 6 by rtoy@chromium.org, Sep 19 2016

Thanks for the updated example. I did get confused on the two nodes.

This is a bug in how the new automation code handles events.

Comment 7 Deleted

We as well encountered this bug, which affects our live product.
I created a simple fiddle that shows exactly the issue: https://jsfiddle.net/kh8y6eeb/
Clicking on the mute button before playing the sound will not mute the gain node.

This is a serious issue for us.
If you need a temporary workaround until the bug is fixed, you can try sending an AudioBufferSourceNode with an empty buffer through whatever nodes you need.

Example: https://jsfiddle.net/kh8y6eeb/3/

This has worked for my project
Thank you for the workaround. It's ugly, but it does the job.

Rtoy, This workaround is also good for https://bugs.chromium.org/p/chromium/issues/detail?id=638823. Is there any connection between these two bugs?

Comment 11 by rtoy@chromium.org, Oct 6 2016

Thanks for the repro case; this should make it easy to figure out what's going on.

Comment 12 by rtoy@chromium.org, Oct 6 2016

Labels: OS-All
Owner: rtoy@chromium.org
Status: Started (was: Available)
This is a bug in an internal optimization for nodes with no inputs.  The automations aren't run.
Project Member

Comment 13 by bugdroid1@chromium.org, Jan 10 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b

commit 69350f73e4ed47dac12cb087ee4bb6ec64a12a2b
Author: rtoy <rtoy@chromium.org>
Date: Tue Jan 10 19:47:18 2017

AudioParams with automations must process timelines

Currently, if an AudioNode has no inputs connected, any automations
(or connections) to an AudioParam of the node is not processed.  Thus,
time never advances on the AudioParam, and any upstream graph
connected to the AudioParam never gets pulled for data.

AudioParam should get processed so that time progresses.  Normal
processing of the node causes AudioParams to be processed, so we were
only missing the case where the node has silent inputs (silent or no
inputs).  Then we just need to update the AudioParams, without having
to do the full processing associated with the node.

See https://webaudio.github.io/web-audio-api/#rendering-loop, step 8.1.1
in particular that says any inputs connected to an AudioParam are
processed.  There are no conditions on when this happens.

BUG= 647974 
TEST=audioparam-processing.html

Review-Url: https://codereview.chromium.org/2420983002
Cr-Commit-Position: refs/heads/master@{#442662}

[add] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-processing.html
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/AudioBasicProcessorHandler.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/AudioBasicProcessorHandler.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/AudioNode.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/BiquadProcessor.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/BiquadProcessor.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/DelayDSPKernel.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/DelayDSPKernel.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/DelayNode.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/DelayProcessor.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/DelayProcessor.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/DynamicsCompressorNode.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/GainNode.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/GainNode.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/PannerNode.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/PannerNode.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/StereoPannerNode.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/modules/webaudio/StereoPannerNode.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/platform/audio/AudioDSPKernel.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/platform/audio/AudioDSPKernelProcessor.cpp
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/platform/audio/AudioDSPKernelProcessor.h
[modify] https://crrev.com/69350f73e4ed47dac12cb087ee4bb6ec64a12a2b/third_party/WebKit/Source/platform/audio/AudioProcessor.h

Comment 14 by rtoy@chromium.org, Jan 11 2017

Status: Fixed (was: Started)
This is great news! What version of Chrome can we except this to be in?

Comment 16 by rtoy@chromium.org, Jan 12 2017

Sorry for taking so long.

I believe this made it into Chrome 57
Just tests on Chrome and 57, and our sample (https://jsfiddle.net/kh8y6eeb/) works as expected. Thank you.

Sign in to add a comment