New issue
Advanced search Search tips

Issue 876917 link

Starred by 6 users

Issue metadata

Status: Started
Owner:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug



Sign in to add a comment

Sound glitch when AudioBuffer has different sampling from device.

Reported by pp.b...@gmail.com, Aug 22

Issue description

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

Steps to reproduce the problem:
1. Open https://jsfiddle.net/4fmypg87/
2. Click on button #2, a case that involves re-sampling
3. Notice sound glitches (in contrast to case #1 without re-sampling)

What is the expected behavior?
No (noticeable) difference in sound, regardless of whether re-sampling is involved or not.

What went wrong?
Audio has a noticeable glitch between queued buffers. 

Did this work before? N/A 

Does this work in other browsers? No
 - Safari: Sound glitch
- Ms Edge 42: Sound glitch
- Firefox 62: Works fine

Chrome version: 70.0.3530.0  Channel: canary
OS Version: 10.0
Flash Version: Shockwave Flash 27.0 r0
 
Works fine for me on OSX, Chrome 69.0.3497.42 and chrome canary.

But this is not surprising.  When the buffer is resampled, the resampling doesn't know that the buffers are appended so the resampling may not fit together as smoothly as you want.
What's your device sample rate? We were able reproduce this only on some devices.

What I'd expect is that result of re-sampling will have matching end and beginning with source data.
 
When re-sampling is done on my side (Emscripten app), then this problem doesn't exits.
Labels: Needs-Triage-M70
In the beginning I thought that it's connected to device 48kHz sampling. So I've changed sound device mode to 44kHz, but the bug is there.
Currently I can reproduce this on:
- MacBook Pro (Retina, 15-inch, Mid 2014)
- Dell Precision 5520 + Windows 10.
- Dell XPS15 9550 + Windows 10


Retried again on my MacBook Pro (Retina 15in) at sample rates of 44.1, 48, 88.2, and 96 kHz. Cannot hear any glitches using headphones.

Also tried on my linux machine at 44.1 kHz (and headphones).  No glitches.

And I made a mistake in my reasoning for the glitches.  I see you are creating a bunch of buffers that are samples from a sine wave.  These should all fit together nicely.

The only thing I can think of now is if buffer.duration is slightly off or if roundoff in updating timeBuffered is causing a buffer to start one (or a few) samples too early or too late.  One way to test this (I can't do it because I don't hear any glitches), is to use buffer.length and update a totalFrames counter and set timeBuffered = totalFrames / context.sampleRate.
I've made some changes to emphasize this glitch: https://jsfiddle.net/4fmypg87/8/
It should be much more noticeable. 

Also I've created a footage: https://www.youtube.com/watch?v=ZHBStSlQBQo where you can hear a buzz on the top of sin-wave. 

The rounding precision problem was a first thought in my mind. I've tried to fix it with Math.fround on my operations, but without success.
Status: Available (was: Unconfirmed)
Ok, that is very clear now.  I think the best way to see what's happening is to use hoch.github.io/canopy to see the generated waveform.  I'll try that out shortly.
Canopy shows a nice smooth waveform.  Something about the real-time context makes it different from an offline context.
876917-test.js
1.2 KB View Download
I'm glad that the issue is visible right now. 
The Canopy is really nice tool! I can confirm that Canopy can render samples into a smooth sound.


Also I've tried to crate AudioContext with sampleRate that matches buffer sample rate, but it didn't work, as I assume that re-sapling will still occur to match the hardware device sampling rate. 

Do you see any obvious solution for this issue, what doesn't involve run-time re-sampling? 
The WebAudio spec allows creating an AudioContext with a user-selectable sample rate.  This would allow you to use your AudioBuffers without resampling (if they're all at the same rate).  Of course, there has to be resampling to get that audio out to the HW if the HW doesn't support your selected rate.

Unfortunately, Chrome hasn't implemented this yet.

Well, that was silly.  In 876917-test.js I set the sample rate of the context to 43800; the same as the buffer.  It should have been set to 44100 (@sampleRate).  When I do that, I hear the glitches.  If you zoom in, you can see glitches every 30 samples. 

I'm attaching the updated test.
876917-test.js
1.2 KB View Download
Ok, I think there's confusion the the buffer source playback on where the output should start and end.

I see that the first buffer produces output for frames 0-30, and frame 30 is 0.96648.  The second buffer produces output for frames 30-60, and frame 30 is .948362.  The output from these buffers get summed together at the destination to produce a value of 1.914842.  And that's exactly what canopy shows as the output at frame 30.

The second frame is scheduled to start at time 0.000684931506849315, which is also the duration of the first buffer.  This time corresponds to a sample frame of 30.20547.  Thus we output a sample at frame 30.  But the buffer actually starts after frame 30, so the first output should happen at frame 31, not 30.  I think that will fix this issue.
Owner: rtoy@chromium.org
Status: Started (was: Available)
I think Chrome needs to implement sub-sample accurate start for ABSN.  I think what's happening now is that if the start frame is 30.2, we output the first sample of the buffer at frame 30.  Then we end up outputting an extra sample due to interpolation, and the extra sample gets added to the first sample of the next buffer.

Instead, the first output should be at frame 31, and we need to interpolate the value because the source started at frame 30.2 and not 31.  So some mix of sample 0 and 1 will be the output.

This seems to work for the canopy test case (no glitches), but more testing needs to be done.

Sign in to add a comment