[Openal-devel] ALC_ENUMERATE_ALL_EXT and pluggable sound devices
Ryan C. Gordon
icculus at icculus.org
Fri Sep 18 18:37:33 PDT 2009
Shoot, I wrote a big reply and Thunderbird ate it. I'll try again...
> Let me divide the pluggable devices problem:
This is a good distinction.
> 1) There should have some mechanism to reset the device listing to get
> any new device connected or disconnected from the system.
ALC_EXT_disconnect specifies this to be alcGetString().
> 2) There are applications that needs to know if some new device was
> connected.
It might be useful for an extension to supply this as an optimization,
over re-parsing the device list (scripting languages aside, even).
> The second problem could be solved by inspecting the USB bus (or
> FireWire, etc) using some kind of O.S. API. But IMHO, OpenAL itself
> should not be responsible for this, as this activity is very complex, if
> you want to implement an efficient approach (the devices API is very
> different between operating systems). But if someone wants to develop
> this mechanism, I think you can do something like:
As the mechanism is platform-specific, it's exactly what _should_ be
abstracted into OpenAL.
> 1) Stefanos solution ( alcGetBoolean(ALC_DEVICE_LIST_CHANGED) ): you
> need to make polling on your program, even if you have a more robust
> implementation in lower-level. For example, tomorrow you find that is
> more simpler and have less cost to receive some kind of system
> notification (that is available on most of current operating systems) in
> the event of a device connection.
(See my notes below.)
> 2) Ryan solution ( new memory allocated on the return of
> alcGetString function ): you will broke the behavior of the function, so
> old code implementations will start to leak memory after this change.
My solution doesn't require allocation. The AL only promises (in
ALC_EXT_disconnect) that the pointer will remain valid until the next
call to alcGetString(), but it might return a pointer to the same static
internal buffer each time. If it wants to return a new string, it can
take that opportunity to free the previous result, as it doesn't need to
keep it around any more.
My example was application code, and it could employ a static buffer,
too, and never allocate at all.
In either case, it doesn't imply a leak in legacy code.
> I would like to receive comments about the above proposal and why you
> couldn't adopt it (I don't know deeply which kind of requirements are
> involved in alcGetString API).
I think if we're going to get a fight about transferring a string
between C code and a managed language, there's going to be war about
adding callbacks.
That being said, there are uses for callbacks. If we ever did some sort
of DSP pipeline like CoreAudio's AudioUnit API, we'd either need to
create a "shader language" (gasp!) or supply a callback mechanism.
But device notification is not a low-latency operation. In treating it
as an event, it's nothing like notifying the app of mouse input. If a
user plugs in a USB audio device, you could very easily run hundreds of
frames before they've even looked back up at the screen...and in any
case, it'll be several seconds between when they plug the device in and
when the OS configures it enough to let OpenAL know it has become
available. So this doesn't need to report it to the app quickly.
In such a case, checking for new devices once a frame (or once every X
seconds) isn't unreasonable.
Now I'll admit, I threw a hissy-fit about using null chars in the device
enumeration list because of what it does to managed languages that have
to deal with a strange string format. So I'm not against adding a way to
tell them they have a new device without regrabbing the device list string.
Here are my notes about this format...
alcGetBoolean(ALC_DEVICE_LIST_CHANGED, &trueOrFalse);
- There's no alcGetBoolean. We could use alcGetIntegerv(), though.
- It's a little annoying to have something that only works with the NULL
device in alcGetIntegerv() ...but it's not a big deal, I guess.
- Is "changed" useful? We don't know if something was added or removed
without checking the list against a previous copy. If we're going to do
this, we should probably make it more useful than just telling you that
you need to reparse the device list.
- Do we report this to be true for each device that changes, or once for
each pile of changes between queries?
- Is this value true or false at startup?
- What happens if the app doesn't check this? Does it report true until
queried, and then resets to false? What happens if they request the
device list without checking this flag?
- I don't think this changes anything about when the AL does device
redetects. It may still have an event queue internally, or be checking
on another thread internally, or do it during the app's query.
This will need a new extension...all the things we're talking about can
coexist with ALC_EXT_disconnect, and won't need to rely on it, either.
One of these things we're talking about could be worked out, I think.
--ryan.
More information about the Openal-devel
mailing list