WebAudio / web-audio-api

The Web Audio API v1.0, developed by the W3C Audio WG
https://webaudio.github.io/web-audio-api/
Other
1.04k stars 165 forks source link

Add AudioRenderCapacity interface and related classes #2462

Closed hoch closed 2 years ago

hoch commented 2 years ago

Fixes #2444.

The PR is ready for rebase/merge.


Preview | Diff


Preview | Diff

samuelweiler commented 2 years ago

Please add an analysis of how much fingerprinting surface this adds to the spec's privacy considerations section. If you think there's none, justify that claim.

hoch commented 2 years ago

Thanks for chiming in, @samuelweiler.

hoch commented 2 years ago

My response to https://github.com/WebAudio/web-audio-api/pull/2462#pullrequestreview-861034880:

How does this work when the buffer size of the device is not aligned on the render quantum size? In its current shape, this proposal only measure the time it took to render a block, and the duration of this block.

It seems more useful to measure the time it took to render a system-level audio callback divided by the buffer size of this system-level audio callback, divided by the sample-rate of this system-level audio stream. Or maybe I'm reading too much when it's written "render quanta", and it's not the same as our "render quanta" in the spec, in which case we probably want to use another term. That may be what "raw capacity value" means.

I also noticed this problem - my approach was to avoid mentioning the underlying callback buffer size and how it is connected to the rendering algorithm. The reason is that the concept is not formally specified. (We only have 2 instances of "system audio callback", and we don't explain or define how it works)

Instead, the current language only cares about the render quantum and the user-specified time interval. We can perhaps clarify by introducing a new section that explains how the Web Audio renderer works with the underlying audio system, but 1) that alone can be a significant spec work and 2) there might be some UA-specific details in this. Not sure if we want this.

An example to make it clear what I mean:

In the (common) case of a buffer size that is 192 frames at 48000 Hz (precisely 4 ms), if we have a graph that has a render quantum of 128 frames / 2.66ms (the default in all implementations for now) and renders in an average of 2ms, it's ceil(2 / 2.66 * 100) = 76.

Yes, but do 192 frames matter? The render quantum and a load value is enough information.

In reality, every other callback, 256 frames of audio need to be rendered, so about 5.32ms (excluding non-linearity effects, I think the point still stands), which underruns. So we're in a situation where the load is lower than 100, but underruns are clearly happening.

I am not following this point - why 256 frames are needed every other callback?

In general, I think we have an agreement on design - but perhaps we are not sure how to solve the uncertainty around the underlying callback, its interval, and how the "batch" rendering mechanism.

padenot commented 2 years ago

I am not following this point - why 256 frames are needed every other callback?

I've tried to make it clear in the link, via a table: since the 128 is not a divisor of 192, when a callback arrives, with a time budget of 4ms (at 48kHz), 256 frames need to be rendered (to have 192 frames to give to the system callback), which means 64 frames are left in a buffer in the browser. Then the next callback comes, 192 frames are needed again, with the same time budget of 4ms. There are 64 frames left in the buffer, so the web browser only has to render 128 frames (128 + 64 = 192) to service the system audio callback. It repeats like this for the lifetime of the AudioContext.

So every callback, with a 4ms budget, we have either 256 or 128 frames to render. This means that an effective load histogram should be bimodal, but it isn't with the current proposed spec text. This is important because it signals to authors that there is a problem and that the maximum load they can have on this configuration is half the maximum theoretical load.

I think it's perfectly workable with the current API shape, though. But in general, I'm afraid that not taking into account the realities of the underlying system will yield an API that is less useful than it could be.

If we shift the API to collect data on the system-level audio callbacks instead of render quanta, it immediately becomes a lot more useful for the user. There is in fact no need for render quanta (in the Web Audio API sense of a block of, for now, 128 frames) to be mentioned.

hoch commented 2 years ago

Conclusion from WG teleconf on 1/27/2022:

hoch commented 2 years ago

@padenot @svgeesus Do we need a TAG review for this?

svgeesus commented 2 years ago

Do we need a TAG review for this?

Need, no.

However, especially if there is an explainer for this, requesting review would be helpful at this early stage. Or we could wait until the Recommendation is republished with the next batch of new features.

hoch commented 2 years ago

@samuelweiler Please take a look at https://github.com/WebAudio/web-audio-api/pull/2462#issuecomment-1011333801 before we merge this change.