AudioBufferSourceNodes scheduled in a sequence aren't seamless even when their sample rate matches context

RESOLVED FIXED in mozilla30



Web Audio
4 years ago
4 years ago


(Reporter: karlt, Assigned: karlt)


28 Branch
Bug Flags:
in-testsuite +

Firefox Tracking Flags

(Not tracked)



(6 attachments, 1 obsolete attachment)



4 years ago
It is expected that AudioBufferSourceNodes having sample rates matching that
of the AudioContext and scheduled in sequence with start times differing by
the buffer duration will play seamlessly.

However, the double parameter representing start time in seconds is rounded
to MediaTime values before rounding to the nearest tick.
This means that the nearest tick rounding is not necessarily the nearest tick.
MediaTime is in seconds with 20 fractional bits providing a resolution of
about 22 parts per 48kHz sample interval.
For an arbitrary starting time, there is about a 1/22 chance of it leading to
adjacent buffers being rounded in different directions.

double variables don't have infinite precision, but even after an AudioContext
has been running for a day, a double seconds parameter still has a resolution
of 2^53/48000/60/60/24 ≅ two million fractional parts per 48kHz sample

Comment 1

4 years ago
Created attachment 8375960 [details]

This schedules 1-sample buffers in sequence at an offset to generate the problem.

Expected result: a horizontal line.
Actual: the graph oscillates up and down as buffers interfere.

Comment 2

4 years ago
Created attachment 8375999 [details] [diff] [review]
move stream time methods from WebAudioUtils to AudioNodeStream

Trying to clear up which stream parameter is which.
Attachment #8375999 - Flags: review?(paul)

Comment 3

4 years ago
Created attachment 8376002 [details] [diff] [review]
round double times to ticks consistently and round to nearest

RoundUp came from
but we're asking for this problem to happen if we round points infinitesimal distances from one tick to another tick.
Attachment #8376002 - Flags: review?(paul)

Comment 4

4 years ago
Created attachment 8376005 [details]
modified testcase showing remaining issue

It is still possible to generate the same problem if aiming for the rounding cliff, but now the timing needs to be within the precision of doubles to do so.

Nodes will usually be scheduled on times offset from zero, or from times provided by WebAudio such as currentTime.  currentTime should be near a tick, so rounding to nearest should work well.

There is still a chance of falling mid-way between ticks if an offset from zero is an odd multiple of 5ms on a 44100 Hz context.  Perhaps we could add a tiny irrational offset to the rounding to avoid problems in this situation.

Comment 5

4 years ago
Created attachment 8376009 [details]
testcase for comparison with blink

I don't know why Chromium doesn't support buffers of length 1.

The changes here mean Gecko now generates the same results as Chromium 33.0.1750.46 for this testcase.


4 years ago
Attachment #8375999 - Flags: review?(paul) → review+


4 years ago
Attachment #8376002 - Flags: review?(paul) → review+

Comment 6

4 years ago
Flags: in-testsuite?
Last Resolved: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla30

Comment 8

4 years ago
Created attachment 8378731 [details]

Here is a Mochitest test case for checking if buffers interfere with each other -- it generates a signal with alternating amplitudes of 1 and -1 every sample. It schedules 2-sample-sized buffers in sequence, and asserts this against a directly generated buffer.

Comment 9

4 years ago
Created attachment 8378791 [details]

This updated version of the test case tests against multiple offsets. It also, instead of using an expected buffer containing a generated version of the scheduled samples, plays the generated buffer with its phase inverted and asserts it against a buffer of zero amplitude throughout.
Attachment #8378731 - Attachment is obsolete: true

Comment 10

4 years ago
Flags: in-testsuite? → in-testsuite+
You need to log in before you can comment on or make changes to this bug.