ABSN reversed playback behavior

Hi Ray and group,

I thought I'd try to put out an explanation of the latest revisions to
https://github.com/WebAudio/web-audio-api/pull/1143 and why I think it
addresses the issues that came up in yesterday's call. I also think this
issue should be made more visible to observers of the WG's activity.

To recap: we have a conflict between two alternate interpretations of what
should happen when playbackRate is reversed on an ABSN that is playing, and
whose playhead position is currently within the looped portion of the
buffer:

1. *The node should play the exact reverse of everything that it has played
up since it started*. In this behavior, the looped portion is played
backwards for only as many iterations as it has already played forwards
(which could be 1 or fewer). This behavior is useful for, say, playing a
musical note that incorporates both an attack and a looped section in a way
that "sounds backwards".

2. *The node should play the loop in reverse, indefinitely*. This is useful
for playing a looped section in reverse for an indefinite period, like a DJ
"scrubbing" a looped sound on a turntable by spinning it backwards, or a
repeating sound effect being played backwards over and over again.

There are clearly two somewhat incompatible use cases here. My argument for
(1) was that it is a simple, literal interpretation of "backwards". However
Ray has made some compelling arguments for (2):

- Without this behavior, there is no practical way to achieve indefinite
backwards looping. I had argued for setting an arbitrary large "offset"
value, but I now realize that this violates the sense of "offset" as an
actual offset constrained by the buffer's physical length.

- It is possible to achieve the effect of (1) without prescribing any
special ABSN behavior, by either unrolling the looped samples or by playing
two ABSNs in juxtaposed sequence, one with the reversed loop and the other
with the reversed attack.

The most recent revision to PR #1143 now specifies behavior compatible with
(2) (I hope!) so that we can evaluate what people think of this approach.
The changes I made were simple: there is a new "enteredLoop" flag that
tracks whether the playhead has ever entered the loop. If this flag is
true, then effectiveBufferTime is allowed to wrap *forward*, mapping
playhead positions prior to actualLoopStart to their corresponding wrapped
positions prior to actualLoopEnd.

In Ray's test case, the enteredLoop flag becomes true immediately because
the offset parameter places the playhead within the loop from the start of
playback. Consequently, the loop will play backwards indefinitely.

In cases where the playhead lies within the "attack" phase of a looped note
sample, though, the playhead would simply play the attack backwards. So
this does partially support the goals of behavior (1).

See
https://rawgit.com/WebAudio/web-audio-api/5d4a6e8b1c3603b5a923f7b0361e2f2078c25389/index.html#playback-AudioBufferSourceNode
for details.

.            .       .    .  . ...Joe

Joe Berkovitz
Founder
Noteflight LLC

49R Day Street
Somerville MA 02144
USA

"Bring music to life"
www.noteflight.com

Received on Friday, 3 March 2017 14:46:27 UTC