Open bgins opened 5 years ago
You mentioned that you could call stop()
with a very large value. That got me thinking. What happens if you call it with an infinite value? If that would be possible it would effectively cancel the previous call to stop()
.
I was curious how the browsers do currently behave because the definition of the stop()
method does not explicitly disallow infinite values. However I get an error in Firefox and Chrome when I run the following example.
const ctx = new AudioContext();
const osc = new Oscillator(ctx);
osc.connect(ctx.destination);
osc.start();
osc.stop(ctx.currentTime + 10);
osc.stop(Number.POSITIVE_INFINITY); // This throws an error.
Both browsers complain that when
is non-finite and stop the Oscillator after 10 seconds.
A lot of other functions like setValueAtTime() and linearRampToValueAtTime() do explicitly mention that they don't accept infinite values but the stop()
method doesn't have that requirement.
Calling stop()
with Number.POSITIVE_INFINITY
makes sense to me. It reads like play forever. If the spec intends this as a possibility, it might be good to mention it.
I don't know why certain methods say they don't accept infinite values, but https://heycam.github.io/webidl/#idl-double makes it pretty clear that double
means finite values and 'unrestricted double` allows non-finite and NaN values.
On the face of it, this seems like a reasonable way to cancel a scheduled stop.Or I guess you can use just some huge value. In practive any value over 2^64
frames is the limit since all (most?) implementations use a size_t
to count frames instead of a double
to count time.
Teleconf: Leave things as is. The user should set a large (finite) value that basically cancels the original stop.
Any details on the reasoning behind this? When I set a large finite value far into the future, I think to myself that I must be missing a better method to do this. In part, this is because the AudioParam
interface provides cancel methods, and I expect that AudioScheduledSourceNode
would have something similar.
There's a bit of a difference from AudioParam
because you can schedule a huge number of events in the future. And without a cancel method, there would be no way to remove them.
The basically conclusion is that it works. Adding an explicit cancellation method doesn't really help. It was suggested that allowing infinity (and/or NaN) would make the intention clear, but the value added in specifying this was deemed too small when the developer could just say stop(1e300)
. Not great, but there it is. 5e14 sec is already greater than age of the universe.
Alright, thank you for the explanation.
F2F: after further discussion with @bgins, re-opening.
I was thinking about this issue after the F2F. I think a decent name for this method would be cancelScheduledStop
. This is somewhat along the lines of cancelScheduledValues
, but also indicates that only one scheduled event will be cancelled (the last invocation of stop).
Also, we discussed whether this method is syntactic sugar for scheduling a stop far into the future. I am not sure whether this is the case. The spec says that:
An AudioScheduledSourceNode is said to be playing when its associated BaseAudioContext's currentTime is greater or equal to the time the AudioScheduledSourceNode is set to start, and less than the time it’s set to stop.
If an AudioScheduledSourceNode
has been set to start, but no stop is ever called, does it implicitly have a stop time? If so, then I think the method would be syntactic sugar.
If not, I think this method might do something different, like resetting the node to a state as if no stop had ever been called.
AudiWG Virtual F2F:
NaN
might behave similarly, discuss passing in unvoluntary NaN
s, or we can throw.
Describe the feature I think that a method to cancel a
AudioScheduledSourceNode.stop()
would be useful. The method would put theAudioScheduledSourceNode
into a playing state indefinitely until a subsequent call tostop()
schedules a new stop time.Is there a prototype? No.
Describe the feature in more detail Currently, the only way to extend the time that an
AudioScheduledSourceNode
will play is a call tostop()
with a time farther into the future than any previous call tostop()
. In some cases, it may be difficult to say for certain when theAudioScheduledSourceNode
should stop playing. We may need to wait for a user to take action to know when to stop.For example, consider an
OscillatorNode
connected to aGainNode
with an envelope (from an envelope generator library) attached toGainNode.gain
. Suppose that a user starts and stops the oscillator from a Midi controller or their computer keyboard. When a user presses a key, the oscillator starts, and when they release the key, we schedule the oscillator to stop once the release phase of the envelope has ended.If a user presses the same key before the release phase has ended, we want to retrigger the envelope and keep the oscillator playing for an indefinite period of time (until the user releases the key again and the envelope's new release phase has ended).
From what I can tell, the only way to do this is to call
stop()
with some huge value assuming that no user would hold a note that long. This is a little unintuitive, and it takes some research for a developer to decide that this is the way to effectively "cancel" astop()
.I think a call to cancel a
stop()
should only happen between the timestop()
is called and the time the queued control message to stop has taken effect.