New issue
Advanced search Search tips

Issue 904244 link

Starred by 1 user

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows
Pri: 2
Type: Bug



Sign in to add a comment

AudioParam.cancelAndHoldAtTime() does not always hold the value during a ramp

Reported by tszynal...@antimoon.com, Nov 11

Issue description

UserAgent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0

Steps to reproduce the problem:
1. Go to http://jsfiddle.net/tszynalski/mby8qr9v/66/
2. Open the console.
3. Press "Start play/stop sequence".

This will execute the following sequence of function calls: play() - stop() - play() - stop(), with about 1 second passing between one call and the next.

The play() function smoothly increases the volume from the current value to 1 over 2 seconds. The stop() function does the same, except it goes to 0.

Each function starts by calling cancelAndHoldAtTime() on the GainNode which controls the volume. Per the W3C spec, this should immediately end any ongoing ramps, and hold the current computed value. The next ramp should start from this value.

What is the expected behavior?
Alternately rising and falling volume, with no pops or other sudden volume changes.

What went wrong?
Starting with the second play() call, there are audible pops. The console logger shows discontinuities in the GainNode value shortly after a play/stop() call. A possible explanation is that the cancelAndHoldAtTime() calls do not properly hold the value of the gain parameter.

Did this work before? N/A 

Does this work in other browsers? N/A

Chrome version: 72.0.3607.0 (64-bit)  Channel: canary
OS Version: 6.1 (Windows 7, Windows Server 2008 R2)
Flash Version: Shockwave Flash 31.0 r0

If this bug is fixed, it will be possible to implement Play / Stop buttons which smoothly fade in/out a sound with a linear envelope, even if a previous fade in/out is already in progress.
 
Labels: Needs-Triage-M72
Cc: swarnasree.mukkala@chromium.org
Labels: Triaged-ET Needs-Feedback
Tried testing the issue on reported chrome version #72.0.3607.0 using Windows 7 and Windows 10 by following steps as per comment#0. The following are the observation noted while testing the issue.

Observations:
===========
1.The sequence of function calls: play(), stop(), play(), stop(), with about 1 second passing between one call and other.
2.The play function increases the volume and when stop is called the value drops to "0".
3.The current volume increases with 1 second when play() function gets called.

Attached screencast for reference.
@reporter: Could you please provide the screenshot or screencast of the issue so that it would be really helpful for further triaging of the issue.
Thanks.!
904244.mp4
7.6 MB View Download
What for? Your screencast shows the values don't change continuously.
Project Member

Comment 4 by sheriffbot@chromium.org, Nov 13

Labels: -Needs-Feedback
Thank you for providing more feedback. Adding the requester to the cc list.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Cc: phanindra.mandapaka@chromium.org
Labels: Target-72 FoundIn-72 M-72 FoundIn-71 FoundIn-70 OS-Linux
Status: Untriaged (was: Unconfirmed)
Able to reproduce the issue on reported chrome version 72.0.3607.0 also on latest chrome 72.0.3616.0 using Ubuntu 17.10 and Windows 10.  

Same behavior is seen on M60(60.0.3112.113) hence considering it as non-regression and marking it as Untriaged.

Note: observed different behavior on Mac

Thanks! 
Status: Available (was: Untriaged)
I hear the some pops in the audio.

Comment 7 by rtoy@chromium.org, Jan 18 (4 days ago)

Owner: rtoy@chromium.org
Status: Assigned (was: Available)
I think this snippet (use hoch.github.io/canopy) shows the problem:

// @sampleRate 48000
// @duration 10
// @channels 1

var oscillator = context.createOscillator();
var fader = context.createGain();
oscillator.connect(fader);
fader.connect(context.destination);

oscillator.frequency.value = 440;
fader.gain.value = 0;
oscillator.start(0);

var FADE_TIME = 2; //seconds
var PLAY_STOP_CYCLE_INTERVAL = 1; //how often to change between play (fade-in) and stop (fade-out)
var LOGGING_INTERVAL = 0.05; //seconds
var MAX_PLAY_STOP_CYCLES = 2;

let playing = false;
for (let k = 0; k < 10; ++k) {
    if (!playing) {
	context.suspend(k)
	    .then(() => {
		    time = context.currentTime;
		    fader.gain.cancelAndHoldAtTime(time);
		    fader.gain.linearRampToValueAtTime(1, time + FADE_TIME)
			})
	    .then(() => context.resume());
    } else {
	context.suspend(k)
	    .then(() => {
		    time = context.currentTime;
		    fader.gain.cancelAndHoldAtTime(time);
		    fader.gain.linearRampToValueAtTime(0, time + FADE_TIME)
			})
	    .then(() => context.resume());
    }
    playing = !playing;
}


At time 1, the ramp up is half done, and we cancel the running event and ramp down.  This is ok.

At time 2, we should cancel the event (ramp down) and start ramping up again.  However, at time 2, we didn't hold the output; it starts at 0 for some reason.  But we ramp up as expected.

At time 3, we cancel and start ramping down.  But instead of holding, the output appears to be 0 already, so ramping down to 0 does nothing.

Assuming the snipped is doing what I think it should be, we can see there's a problem in cancelAndHold, at least at time 2.  Not sure what's happening at time 3.

Sign in to add a comment