Skip to content

fix: enforce spec limits for ConvolverNode.buffer and allow 32-channel buffers - #1258

Open
giaBaoJS wants to merge 1 commit into
software-mansion:mainfrom
giaBaoJS:fix/convolver-buffer-channel-limits
Open

fix: enforce spec limits for ConvolverNode.buffer and allow 32-channel buffers#1258
giaBaoJS wants to merge 1 commit into
software-mansion:mainfrom
giaBaoJS:fix/convolver-buffer-channel-limits

Conversation

@giaBaoJS

Copy link
Copy Markdown

No linked issue: found by reading source against the Web Audio API specification.

⚠️ Breaking changes ⚠️

Setting ConvolverNode.buffer to an impulse response with an unsupported
channel count, or with a sample rate different from the context's, now throws
NotSupportedError instead of silently configuring the convolver. This is the
behaviour the spec requires and the behaviour browsers already have, but code
that relied on the previous permissive setter will now see an exception.

Introduced changes

  • ConvolverNode.buffer setter now runs the spec's setter steps. Web Audio API
    §1.17.2: "If the buffer number of channels is not 1, 2, 4, or if the
    sample-rate of the buffer is not the same as the sample-rate of its associated
    BaseAudioContext, a NotSupportedError MUST be thrown." Previously the only
    channel-count check lived in ConvolverOptionsValidator, so it ran for a
    buffer passed through the constructor options and never for a later
    assignment. The sample-rate condition was not checked anywhere, and the native
    ConvolverNodeHostObject::setBuffer has no guard of its own, so a 31-channel
    impulse response was accepted and allocated one convolver per channel.
  • AudioBuffer / createBuffer now accept 32 channels. The bound was written
    numberOfChannels >= 32 while the error message on the next line reports the
    range as [1, 32] and MAX_CHANNEL_COUNT is inclusive everywhere else in the
    engine. §1.1.2 requires an implementation to support at least 32 channels.
    Same one-line fix in the three web-core copies.
  • Added tests/convolver-buffer.test.ts covering both.

Measurements

WPT smoke profile, before and after on the same build:

before after
overall 2631/3301 2664/3303
the-convolvernode-interface 170/253 203/255

wpt-compare.mjs reports no regressions in any of the other 27 sections.

convolver-channels.html was aborting mid-task: it calls
context.createBuffer(count, 1, sampleRate) for count 1..32 outside the
should() wrapper, so the 32-channel call threw and killed the task at count
31. With both fixes it now passes all 32 of its assertions.
ctor-convolver.html's "illegal sample rate buffer throws NotSupportedError"
also passes now; its three remaining failures are unrelated (missing
DynamicsCompressorNode, the clamped-max default for channelCountMode, and
channelCount option validation).

No render-path code changed. The new checks run in a JS property setter at
graph-configuration time, and no C++ file is touched.

Splitting this, if you prefer

The two fixes are separable and I am happy to split them into two PRs on
request. The AudioBuffer bound is a strictly more permissive bug fix with no
behaviour change for anything that worked before; the ConvolverNode setter is
the actual behaviour change. They are bundled here only because
convolver-channels.html needs both to stop aborting, so neither one alone
makes that file pass.

Checklist

  • Linked relevant issue
  • Updated relevant documentation
  • Added/Conducted relevant tests
  • Performed self-review of the code
  • Updated Web Audio API coverage
  • Added support for web
  • Updated old arch android spec file

On the three blank boxes: there is no issue to link, as noted at the top. The
WPT coverage summary is regenerated by maintainers with yarn wpt:report:docs,
which needs a second run against the published release in apps/common-app,
and the interface support table itself does not change here. The Android
old-arch spec file is unaffected, since no native or spec surface changed.

…l buffers

The ConvolverNode buffer setter accepted any impulse response, so a buffer
with an unsupported channel count or a sample rate different from the
context's reached the engine instead of throwing NotSupportedError. The
existing channel-count check only ran for buffers passed through the
constructor options.

AudioBuffer rejected 32 channels while its own error message and
MAX_CHANNEL_COUNT both treat 32 as the inclusive upper bound, and the spec
requires implementations to support at least 32 channels.

WPT the-convolvernode-interface goes from 170/253 to 203/255 passing
assertions; convolver-channels.html now passes all 32 of its assertions and
ctor-convolver.html passes the illegal-sample-rate case.
@closetcaiman closetcaiman added fix Code changes specifically addressing and resolving a bug web-api-spec Implementations, updates, or parity alignment with the W3C Web Audio API specification pkg:audio-api Core React Native audio control system compliant with the W3C Web Audio API spec labels Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Code changes specifically addressing and resolving a bug pkg:audio-api Core React Native audio control system compliant with the W3C Web Audio API spec web-api-spec Implementations, updates, or parity alignment with the W3C Web Audio API specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants