[Openal-devel] ALC_ENUMERATE_ALL_EXT and pluggable sound devices

Chris Robinson chris.kcat at gmail.com
Fri Sep 18 16:41:56 PDT 2009


On Friday 18 September 2009 11:28:49 am Guilherme Balena Versiani wrote:
> Stefanos A. wrote:
> > Besides, why allocate a new string every 5 seconds when you could just
> > say:
> >
> > if (alcGetBoolean(NULL, ALC_DEVICE_LIST_CHANGED))
> > {
> >     // retrieve device list
> > }
> >
> > ?

A problem may be in situations where the implementation can't properly 
retrieve messages from the OS/sound API about device changes. In such cases, 
even getting a boolean about device changes may incur a reprobing of devices 
anyway. Sure, you may save on not having to pass the string back to the 
program, but I think that's comparatively minor compared to the work already 
done.

>     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.

The string(s) returned by alcGetString/alGetString are controlled by OpenAL. 
When OpenAL frees that memory, it's gone.. the app doesn't need to do anything 
to it. And apparently it's already not guaranteed that successive calls to 
retrieve the device list will return the same memory.

For languages with GC, I don't see why it wouldn't catch the references to the 
old strings being lost when a new set is allocated and given to the app, 
initiating a background cleanup of them.


FWIW, I don't think it's that bad of an idea to just retrieve the list every 
few seconds. If the cost of alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER) is 
too high, then can't you run it in a background thread? Something like:

volatile bool ListUpdated = false;
thread 1:
...app loop...
    if(ListUpdated) {
        lock(&device_update_mutex);
        copy_strings(MyInternalList, StringsFromAL);
        ListUpdated = false;
        unlock(&device_update_mutex);
        ListUpdated();
    }
...end...

thread 2:
   while(!KillMeNow) {
       lock(&device_update_mutex);
       StringsFromAL = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
       ListUpdated = true;
       unlock(&device_update_mutex);
       Sleep(1000);
   }

Then all the reprobing and extra allocation/conversation necessary will happen 
away from your main loop, so it should continue on at full speed. The cost to 
your main loop would be every second or so just having a copy and whatever 
updating you need to do to have the new internal list used.

Additionally, if you wanted, thread 2 could do a compare between the new 
strings from AL against MyInternalList, and only mark ListUpdated if they 
differ. Then your main loop wouldn't incur any cost unless the devices 
actually changed.


More information about the Openal-devel mailing list