[Openal] Defective ALC_ENUMERATION_EXT support on Mac OS X / Need OpenAL community's support

Chris Robinson chris.kcat at gmail.com
Tue Jan 6 21:28:23 PST 2009


On Tuesday 06 January 2009 19:46:07 Ryan C. Gordon wrote:
> > To me, it seems out of place for the app to have to check the device
> > itself. Everything else you do when working in the context is done
> > through the context, and needing to keep around and regularly use a
> > device handle because of the potential event that a device can be lost
> > seems a bit unnecessary (especially when you consider you don't
> > necessarilly have a device handle when you use things like alut or
> > alure). You can always get them after you determine the problem, but I
> > don't think you should need them otherwise.
>
> The proper granularity is the device, I think...multiple contexts on the
> same device would all go when the USB stick is pulled out.

I don't see much of a problem when that's checked through an AL call. All 
contexts could determine if the device is still available when a specific call 
is checked, so all contexts on the device can show "device lost" as needed. 
Using GL as an example, you don't typically use GLX/WGL calls once the context 
is setup.

> As for ALUT, this doesn't seem like a deal breaker to me:
>
> bool stillConnected()
> {
>      ALCint yesOrNo = 0;
>      alcGetIntegerv(alcGetContextsDevice(alcGetCurrentContext(),
>                     ALC_CONNECTED, sizeof (yesOrNo), &yesOrNo);
>      return (yesOrNo != 0);
> }

Yeah, it's not difficult, even with proper error-checking. Just seems out of 
place to handle ALC directly regularly.

> I think the CoreAudio model is just too compelling here, and I expect
> that most other platforms won't take advantage of this. We only do this
> with the default device, since that is sort of like telling the AL that
> you don't really care, please make a best decision for me. It just
> continues to do so thereafter. If you request a specific device, it
> shouldn't ever switch out from under you.

I'd think an implementation could do that by exposing a meta-device, of sorts. 
Like how OpenAL Soft gives a "ALSA Software on default" device, if the current 
default device is disconnected, it could reopen the new default device, and 
continue on with that, leaving the app none-the-wiser. Open a specific one, 
like "ALSA Software on HDA NVidia [ALC883 Analog]", and it wouldn't.

IMO, letting work through meta-devices would be better overall than only 
specifying that NULL can do it. It allows implementations to be smarter about 
device groups, even possibly giving more options for the user (eg. don't 
switch to speakers if these headphones are lost).

> We can say that the string is valid until the next call to
> alcGetString(device, ALC_DEVICE_SPECIFIER). The implementation has to
> either cache the current string, or only do device redetects when
> ALC_DEVICE_SPECIFIER is requested. I'll clarify this in the spec.

Sounds a bit safer, but maybe still a bit problematic in multi-threaded 
situations (then again, AL itself isn't the greatest when dealing with 
threads..).

> Even in the case that Restore() succeeds, your data is still gone and
> has to be reuploaded. At which point, you're really not doing much
> differently in this extension, where you close and reopen the device.
> The only thing Restore() adds is that it would, in theory, handle
> finding the device for you, if that actually works at all.

I wouldn't say that. All the existing objects would remain, and the state 
would remain. You wouldn't need to worry about a device getting selected that 
may have lesser capabilities than what you set up with, or risk failure during 
reinitialization leaving you in a bad state. Anything holding handles to AL 
objects won't have issues.

Given that OpenAL is working off OpenGL's example, AL could take care of 
restoring clobbered buffers for you automagically when restored, just like GL 
restores lost textures. If you close/reopen the device, you pretty much need 
to restart the app's sound system in the middle of play, whereas restoring it 
could leave you as you were.

> For what it's worth, I hate that every entry point in DirectX can fail
> with device loss. It is, strictly speaking, an error condition, but it's
> more like an exception, so checking it once a frame seems more
> reasonable to me.
>
> Also, OpenGL's evolution proved interesting: calling glGetError() can
> stall the GL. All pending operations have to finish before it returns,
> and (theoretically) correct programs should never generate an error, so
> modern programs _never_ call it, except in debug builds...things that
> would force OpenAL apps to call alGetError() all the time, or even once
> a frame, should be special-cased like this extension does.

True enough. My initial idea was to use a query API, like GL has:

alGenQueries(1, &qID);
alBeginQuery(AL_DEVICE_STATE, qID);
...
ALint state;
alQueryObjectiv(qID, AL_CONNECTED, &state);
if(state == AL_FALSE) {
     // Device is lost..
}
...
alEndQuery(AL_DEVICE_STATE);
alDeleteQueries(1, &qID);

The device-state query in particular can have other parameters associated with 
it, such as AL_LATENCY to get the amount time it would take for a source to 
start and actually be heard, which could be context-specific. The query API 
itself can be reused for other things, like reading the DSP/hardware timer or 
GL-like fencing (determining when commands have actually been processed; eg. 
if setting AL_GAIN to 0 has taken effect so you can safely call alSourceStop 
to stop without clicks/pops, on implementations that do volume ramping).


More information about the Openal mailing list