OpenAL - Enumeration with OpenAL on Windows

OpenAL

Enumeration with OpenAL on Windows

Introduction

Enumeration allows an OpenAL application to determine what output devices are available for OpenAL to use. Without enumeration, OpenAL will output to whatever device is selected in Windows as the preferred output device. Using enumeration, the application can present the user with the option of selecting a device other than the preferred output device or allow selection of alternative implementations.

This document will go into detail explaining how the enumeration extension works under Windows. The enumeration extension is supported by the library installed by the OpenAL Installer distributed by Creative Labs. The Windows part of the OpenAL source tree contains all the source code.

Note that an OpenAL 1.1 programmer needs to be aware of enumeration issues when writing Windows applications. If a product uses the system-wide implemenation of OpenAL under Windows, the default device assigned may be either a 1.1 or a 1.0-compliant device. If the product uses 1.1 calls on the 1.0 device, then the results will be unpredictable at best. Sample code handling enumeration and device filtering issues (which can be copied into your projects) is provided in the OpenAL 1.1 SDK for Windows.

Usage

This extension provides for enumeration of the available OpenAL devices, and is always available under OpenAL 1.1. Under OpenAL 1.0 or 1.1, a query can be made for enumeration support. If the extension query (for ALC_ENUMERATION_EXT) returns AL_TRUE, then an alcGetString query of ALC_DEVICE_SPECIFIER with a NULL device passed in will return a list of devices. Each device name will be separated by a single NULL character and the list will be terminated with two NULL characters.

Basic Structure

Important Files
[SYSTEM]/OpenAL32.dll <-- "router" OpenAL library
[SYSTEM]/wrap_oal.dll <-- "wrapper" OpenAL library
[SYSTEM]/ct_oal.dll <-- "native" Creative library
[SYSTEM]/nvopenal.dll <-- "native" NVIDIA library

The "router" DLL is an OpenAL DLL which enumerates and makes available OpenAL implementations in other DLLs. If you run the Creative OpenAL Installer, a DLL called "openal32.dll" will be placed in the system directory -- that DLL is a router DLL.

The "wrapper" DLL is a DLL which wraps other audio APIs. The "wrap_oal.dll" library exposes two OpenAL implementations -- "Generic Hardware" (using DirectSound 3D) and "Generic Software" (using either DirectSound or MMSYSTEM). Each of these implementations will be enumerated as a separate "device."

You may end up with other "native" OpenAL libraries in your system directory as well. If you have a Creative Audigy, Audigy 2, Audigy 4, or X-Fi audio card, there will be a ct_oal.dll library in your system directory (after running the Creative OpenAL installer at least -- up till then this library may have been named "openal32.dll"). If you have an NVIDIA NForce motherboard, you may also have a DLL called "nvopenal.dll" in your system directory. These are "native" implementations which directly access the hardware. With the exception of the NVIDIA library "nvopenal.dll," all native implementations will fit the *oal.dll naming convention.

If your application launches and finds the router DLL in the system directory, then the router will use one of the other implementations. If the application enumerates available devices, then the app will get to choose which one to open. If the application opens the default device (NULL), then the router will choose the "best" one.

The best implementation (for the default device case) is determined as follows --

1) Is there a native implementation available which matches the default output device as reported by Windows? If so, that will be the default device. If not, move to #2...

2) Can we use the "Generic Hardware" device, or is the reported hardware too lame to use it? If the "Generic Hardware" device works, it will be the default device. If not, move to #3....

3) Can we use the "Generic Software" device? If not, then alcOpenDevice returns NULL.

Search Order

The router DLL looks in the directoy containing the router itself (unless the router is in the system directory), then the current directory, then the application's directory, and then the system directory in that order. If multiple implementations are found that have the same name, the first implementation found is used.

Application Deployment

Here are three ways:

1) The least complicated...

a) Run the Creative OpenAL Installer in silent mode (with the /s option) along with your installer.
b) Dynamically link with "openal32.dll", which is expected to be found in the system directory, and should find "wrap_oal.dll" as an available implementation, but may find others.
c) Enumerate the available devices and filter out devices which don't match your application's requirements.

2) A more conservative approach...

a) Run the Creative OpenAL Installer in silent mode (with the /s option) along with your installer.
b) Install a version of "wrap_oal.dll" in your application's directory which was tested by the developer and/or the developer's company.
c) Dynamically link with "openal32.dll", which is expected to be found in the system directory, and will use "wrap_oal.dll" from the application's directory, but will enumerate other implementations if found.
d) Enumerate the available devices and filter out devices which don't match your application's requirements.

3) A very conservative approach...

a) Install a version of OpenAL under any name in any location you want.
b) Dynamically link with your implementation of OpenAL.
c) Optionally allow the user to tell the app (through an INI file or the interface) to use a system-wide implementation of OpenAL elsewhere.
d) Before loading the user's selection, make sure that the selected device supports your application's required spec revision and/or required extensions.