[Openal-devel] ALC_ENUMERATE_ALL_EXT and pluggable sound devices
Chris Robinson
chris.kcat at gmail.com
Thu Sep 24 11:13:14 PDT 2009
On Thursday 24 September 2009 10:16:12 am Guilherme Balena Versiani wrote:
> Does soft_oal.dll built from GIT current support updating the device
> list for every call to alcGetString? (Surely I will test, but if you
> have any directions, it would be fine)
Yes. It ultimately relies on DirectSound (for playback) and WinMM (for
capture) to actually enumerate new devices when queried, but AFAIK, they
should.
> > FWIW, the router itself can't directly support ALC_EXT_disconnect. The
> > ALC_CONNECTED token only works on non-NULL device handles and the rest of
> > the behavior is specific to the given device (nothing the router
> > explicitly handles). The router just needs to not assume a static device
> > list from the drivers.
>
> That said, I will start to make changes to OpenAL Router for Windows (at
> first place) to support this behavior. Could you tell me if there is
> some new version of OpenAL Router other than the official repository at
> Creative?
I'm not too sure if the router code on SVN is still up to date or not. I
*think* I read it was, or at least wasn't changed significantly, but that was
a while ago. I know the wrap_oal driver code isn't up-to-date.
If you're going to modify the router code on SVN, there's some things you need
to be very careful of. These things bit me pretty hard when I was implementing
it for OpenAL Soft.
First is (obviously) to make sure you don't leak the previous strings (change
the malloc calls to realloc, or free the old pointers first). Also be careful
that querying the default devices will also trigger rebuilding the list. You
can't have that happen, or else code like this:
const char *strlist = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
const char *strdef = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
could leave strlist as an invalid pointer. Additionally, querying the device
list will change the default device, so this can fail, too:
const char *strdef = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
const char *strlist = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
The way I handled this was to only build the list when the list was queried,
and find the default device from the existing list when that was queried (ie.
don't rebuild the whole list when the default device is requested, and don't
change the default device when the device list is requested).
As a consequence of this method, it should be encouraged to query the device
list first, before the default device name, or else the default device name
may be a disconnected device not found in the device list. I know some code
likes to query the default first, then the list.
One more point is, be careful to only rebuild the list being queried. Or else
this:
const char *pblist = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
const char *caplist = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
can leave pblist as an invalid pointer due to the capture device list query
changing the playback device list.
Essentially, you need to break BuildDeviceList() into six functions..
BuildDeviceList - query the DLLs and build the playback device list
BuildCaptureDeviceList - query the DLLs and build the capture device list
BuildAllDevicesList - query the DLLs and build the all-devices list
FindDefaultDevice - find the default device in the playback device list
FindDefaultCaptureDevice - find the default device in the capture device list
FindDefaultAllDevices - find the default device in the all-devices list
Call the three Build* functions in DllMain under DLL_PROCESS_ATTACH (so an app
that queries the default device first has something to look in), and make sure
to call the appropriate one for the various alcGetString queries.
More information about the Openal-devel
mailing list