[Openal] Problem with getting the correct STATE of a source in NVIDIA implementation.
E. Wing
E. Wing" <ewmailing@gmail.com
Fri, 29 Apr 2005 17:28:32 -0700
> From: "Stephen Holmes" <SHolmes@nvidia.com>
> To: "Keshav Channa" <kbc@dhruva.com>, <openal@opensource.creative.com>
>
> Hi Keshav,
>
> In our implementation, we do not change the state for queued sources
> when the end is reached in case the stream accidently starved. If we
> did, there are many times when we have encountered this condition, only
> to have applications submit more buffers and leave the state in the
> stopped state. For a single buffer source, you should get a AL_STOPPED
> state when the end is reached because we know that there will not be any
> more buffers coming down. If you are expecting this state change for
> queued sources, this may be another condition that should be looked into
> for the 1.1 specification as I don't think it's a 1.0 requirement. I
> would argue against this change though on queued sources for the reason
> I stated above.
>
> For a "fool proof" way of determining whether a sound is playing, you
> can look at the number of buffers that have been processed. This should
> work on any implementation as well.
>
> Regards,
> Steve
>
Drat! You just described my Doomsday / Nightmare scenario. I found a
hard to reproduce bug in Apple's CoreAudio OpenAL implementation
(Radar ID: 4085888) where in some cases, the final buffer that gets
played does not get marked as processed. So this "fool proof" way is
now broken.
The only thing I see in the spec that might be an issue with this
implementation is that alSource( source, AL_BUFFER, AL_NONE) is
described as returning an INVALID_OPERATION on a PLAYING source (p.
29-30 on the annotated 1.0 spec). I've found other inconsistencies
between different implementations on the final buffer state, so I've
resorted to explicity clearing the source everytime I think I'm done.
I don't think the Nvidia implementation has bitten me with the
INVALID_OPERATION so far though (which I'm happy about).
I do think there is merit in the way Nvidia handles this. Most of my
hardware is slow and old so I have been able to produce buffer
underflow situations quite easily. I'm always playing guessing games
with my OpenAL state about why something happened. Did I stop because
I underflowed or because I'm actually out of data? Because of all the
minor distribution subtlies (and bugs) I've found, determining this
information has actually been really hard to do.
Particularly with the non-Nvidia distributions where the state becomes
AL_STOPPED, in some of the bad cases, I end up playing the final
buffer twice (because I have to call alPlaySource again to handle the
underflow) because I thought I still needed to play one more buffer,
but it turns out I had already played it.
So I think there is merit in the way Nvidia approaches this problem.
On the other hand, I think trying to make determinations about OpenAL
based on indirect observations (e.g. buffers processed) is a painful
way of getting to something (especially in light of spec-issues and
bugs). There also may be valuable information from knowing that you
underflowed (you might be able to adjust your CPU requirements in
realtime).
So maybe for 1.1, we should consider a more explicit feedback system
for describing the OpenAL state. Maybe this could be achieved by
introducing something like an AL_UNDERFLOW state. I do like Nvidia's
approach of not making you call Play again on underflow. So maybe in
this state, if you append more buffers, it will continue playing for
you. And if you call alSource( source, AL_BUFFER, AL_NONE) in this
state, it will change the state to AL_STOPPED.
Thanks,
Eric