Scheduling WebAudio events at time = 0 - often get ignored or set in past
Reported by
linb...@gmail.com,
Jul 26
|
|||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36 Steps to reproduce the problem: Simply open the HTML file and keep refreshing the page, paying close attention to the very first notes that play. (Check your volume) What is the expected behavior? When refreshing the page, the song loop should start the playback exactly the same each time. Only the start matters, hence the requirement of refreshing. What went wrong? The start of the song is often incorrect, missing one ore more scheduled notes at the very start, and this differs on each refresh. The song is supposed to start at time = 0, however, the debug log often reports values -0.021333333333333333 and -0.010666666666666666 instead. My guess is that Chrome is incorrectly scheduling events in the past at random, causing them to not be triggered. Did this work before? Yes Does this work in other browsers? Yes Chrome version: 68.0.3440.75 Channel: stable OS Version: 6.1 (Windows 7, Windows Server 2008 R2) Flash Version: Both Firefox and Edge do not have this problem. I tested on both Win7 (happens much more often) and Win10 (requires more refresh attempts to notice a difference). I believe this is a regression, as this was not a problem in January 2018 when I last tested these files. It was definitely not a problem when I was working on the synth code last year.
,
Jul 26
This issue can be worked around by simply adding a bit of delay to the scheduler. I changed the start time from 0 to 0.1, and the issue essentially disappeared. With that change the debug logs are no longer in the negative, but are less than 0.1: Scheduling sequence... buffering 0.08933333333333333 seconds ahead Scheduling sequence... buffering 0.07866666666666668 seconds ahead
,
Jul 26
,
Jul 26
,
Jul 27
@reporter : The given file buffered.zip is not getting extracted. Could you please provide any other sample file so that it would be really helpfull for further triaging. Thanks.!
,
Jul 27
Sorry, here is a plain HTML file. The zip uses LZMA compression from 7zip which I guess Windows doesn't support. My bad.
,
Jul 27
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
,
Jul 30
Able to reproduce the issue on reported chrome version #68.0.3440.75 and on latest canary #70.0.3506.0 by following the steps as per comment#0 using Windows 7,Ubuntu 17.10 and Mac OS 10.13.5.The audio does not play on M-66, M-67 until chrome version #68.0.3427.0 but the audio plays from version #68.0.3428.0 with bad behaviour. Hence could not provide bisect information and marking it as untriaged. Requesting anyone from Blink>WebAudio team to look into this. Thanks.!
,
Jul 30
,
Jul 30
Not able to reproduce this in Chrome 68 on Mac OSX. Will try on Windows soon. A couple of issues. You're scheduling things through a worker, so there's a hop between the main thread and the worker. The audio context runs a different thread, so times may not be quite what you expect. Also, it takes a bit of time to create the necessary waveforms for the oscillators which causes a delay too. This happens on the main thread so the audio thread may have advanced it's clock already. (I suspect this is only a problem on slower machines.)
,
Jul 30
@rtoy I have some additional code samples that may help narrow things down. Keep in mind the first scheduling run isn't through web worker - just subsequent ones for loop purposes. 1. (nowebworker.htm) a much earlier version (synth is only 30 lines), does not use Web Workers, instead using `onended` event for looping, but *still* exhibits the issue (Tested on both Win7/Win10 machines). 2. (worksfine.htm) does *not* exhibit the issue (no idea why). It is more recent version of the Web Worker version with more complicated synth code, but I removed unnecessary components to better compare with the others.
,
Jul 30
Thanks for the updated files. On my linux box, I can hear that occasionally the first few notes are missing. That shouldn't be happening because starting an oscillator in the past just means starting it now. Unless the end time has already passed. Need to dig into this a bit more....
,
Jul 30
Added some debug prints in my local build to see what's really going on. Here is one example: 0xccd1a6a84e8: setValueAtTime(0, 0.01161) @0.01161 start(0) @ 0.01161 0xccd1a6a8488: setValueAtTime(739.989, 0) @0.01161 0xccd1a6a84e8: setValueAtTime(0.2, 0) @0.01161 0xccd1a6a84e8: setValueAtTime(0, 0.164706) @0.01161 The first output line comes from amp[j].gain.value = 0. Since we're using the value setter, it sets the gain to zero can the context time, which is 0.01161 in this case. This is ok. The start(0) line comes from osc[j].start(0) but the context time is already 0.01161. This is ok. The oscillator will start at time 0.01161. This is ok. The line setValueAtTime(0.2, 0) @0.01161 is the interesting one. Because you think time is 0, you're setting the amp gain to 0.2 at time 0, but the actual time is 0.01161. This causes Chrome to insert this event at time 0, *preceeding* the event setValueAtTime(0, 0.01161). Hence when the timeline is run, setValueAtTime(0, 0.01161) is the one that is important since the other one is now in the past. Thus, this oscillator doesn't produce any output, even though it was started. This is a bug in Chrome. The automation time is supposed to be clamped to currentTime. (https://webaudio.github.io/web-audio-api/#dom-audioparam-setvalueattime-starttime). Implementing this should fix this problem. I know this was just a demo, but you really do need to schedule things in the future when possible. Also, the loop for(var i = 0; i < SONG.seq[j].length; i++) does a significant amount of work for some SONG.seq[j] so the current time is advancing while you're doing this using the old value of current time. That can mess up some o the values.
,
Jul 31
@rtoy Nice investigating, looks like you found what was causing it. Removing the line `amp[j].gain.value = 0` fixes the bug in all cases for me, definitely the culprit. Will steer clear in the future. I do remember seeing a developer message advising against using "AudioParam.value" directly and to instead use setValueAtTime, due to clamping or something, maybe related. Hopefully it will be fixed in time when whatever that is gets implemented. Cheers!
,
Jul 31
The warning was probably because we were changing the behavior of the value setter by removing the (unspecified) dezippering behavior, which made it equivalent to setValueAtTime(). And if you wanted dezippering, you should use setTargetAtTime() with a suitable time constant (probably around 10-50 ms).
,
Sep 11
Some of the issues raised here will go away with the latest spec change: https://github.com/WebAudio/web-audio-api/issues/1712#issuecomment-419162528 We won't be clamping events to context.currentTime anymore. If you accidentally set them in the past, they will stay in the past.
,
Sep 27
Probably won't be working on this for a bit. |
|||||||||
►
Sign in to add a comment |
|||||||||
Comment 1 by linb...@gmail.com
, Jul 26