Repository navigation
AudioBufferSourceNode: start() offset prose inverts the negative-playbackRate loopStart comparison #2690
Description
The prose describing the offset argument of start() states the negative-playbackRate clamp with the comparison inverted relative to the normative playback algorithm. Read literally it makes the offset argument almost useless whenever loop is true and the rate is negative. It appears to be a transcription error from #2031.
Current text
From the offset argument of start():
If
offsetis greater thanloopEnd,playbackRateis positive or zero, andloopistrue, playback will begin atloopEnd. Ifoffsetis greater thanloopStart,playbackRateis negative, andloopistrue, playback will begin atloopStart.
What the normative algorithm says
From the playback algorithm:
if (!started) {
if (loop && computedPlaybackRate >= 0 && offset >= actualLoopEnd) {
offset = actualLoopEnd;
}
if (computedPlaybackRate < 0 && loop && offset < actualLoopStart) {
offset = actualLoopStart;
}
bufferTime = offset;
started = true;
}| Rate | Algorithm clamps when | Prose says clamp when |
|---|---|---|
| positive or zero | `offset >= actualLoopEnd` | `offset` greater than `loopEnd` ✓ |
| negative | `offset < actualLoopStart` | `offset` greater than `loopStart` ✗ |
The positive-rate sentence agrees with the algorithm. The negative-rate sentence inverts it.
Why this looks like a typo rather than an intentional rule
Issue #2031, which requested this sentence, asked for the opposite comparison:
The similar instruction "For negative playbackRate, if offset is less than loopStart, playback will begin at loopStart (and immediately loop to loopEnd)" applies in the other case.
Implementations and tests
webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-playbackrate-negative.html in WPT covers both directions, and encodes the algorithm's reading:
- "AudioBufferSourceNode clamps offset to loopStart for playbackRate < 0" — 8-frame buffer,
loopStartframe 4,loopEndframe 6, offset frame 2. Since the offset is belowloopStart, it is clamped, expecting[5, 6, 5, 6]. - "AudioBufferSourceNode loops backwards with negative rate (offset in loop)" — the configuration in the table above, where the offset is above
loopStart. It is not clamped, expecting[3, 2, 3, 2, …].
Under the prose reading the second test would expect [2, 3, 2, 3, …].
Implementation status:
- Chrome — clamps only when the playhead is below the loop start (
if (is_looping_ && virtual_read_index < virtual_start_frame)inAudioBufferSourceHandler), matching the algorithm. - WebKit — currently begins playback at
loopStartin this configuration, matching the prose reading, and fails the second subtest above. - Firefox — It seems it does not implement negative
playbackRateat all?;ComputeFinalOutSampleRatereturns the buffer sample rate when the computed rate is not positive, so a negative rate plays forward at 1×. Not informative for this question.
Activity
cdumez commentedon Aug 4, 2026
cc @padenot
MaheshBharadwaj commentedon Aug 19, 2026
Upon discussing during the audio WG, we decided to update the wording for offset to read in order to honor the algorithm
AudioBufferSourceNode ignores the start() offset for a negative playb…