[openal] ALC_SOFT_HRTF proposal
Chris Robinson
chris.kcat at gmail.com
Sat May 16 19:45:29 EDT 2015
Here's an initial draft for an ALC_SOFT_HRTF extension, which allows
requesting and querying HRTF mixing. It's fairly basic, but it should be
good enough to work.
Something to note: OpenAL Soft currently treats
{ALC_HRTF_SOFT,ALC_FALSE} as a "don't care" request rather than a "do
not use HRTF" request. That is, it won't specifically request HRTF, but
if something else makes the lib want to try (for example if headphones
are detected), it may still opt to use it. This is because OpenAL Soft
treats the HRTF request as a boolean flag. I'm not sure how to best
handle this since I know HRTF options are usually presented as an on/off
boolean state, when it would otherwise need to be used as an
on/off/default state here.
Feedback is very welcome.
-------------- next part --------------
Name
ALC_SOFT_HRTF
Contributors
Chris Robinson
Contact
Chris Robinson (chris.kcat 'at' gmail.com)
Status
In progress.
Dependencies
This extension is written against the OpenAL 1.1 specification.
Overview
This extension allows an application to request HRTF mixing and determine
the status of HRTF mixing. HRTF, or Head-Related Transfer Function, is a
method of mixing 3D audio for true 3D panning, typically using predefined
FIR filters designed to reproduce how a sound is affected by a listener's
head as the sound waves travel around the head.
As a 3D sound API, OpenAL's design allows implementations to render 3D
audio using HRTF. In fact, a few well-known implementations can already do
this without needing any input from the application. However, currently
the OpenAL API has no concept of HRTF so there is no way to query if HRTF
is being used, and no way for an application to provide an option to use
it.
Issues
Q: If implementations can already use HRTF, why is an extension needed?
A: Although implementations can use HRTF, there is no way for the app to
know if it's being used. At the very least, an app may want to alert
the user to whether HRTF is being used or not, and why it's being used
or not.
Additionally, a user may not know how to enable HRTF through a given
implementation's configuration, and it is not always possible for an
implementation to detect when HRTF should be used. The request is only
a hint however, so if an implementation needs to ignore it for whatever
reason, it can, and still provide feedback to the app about why.
Q: It is not unlikely for an implementation to be able to provide multiple
different HRTFs for different purposes (head measurements, quality,
etc). How is this handled?
A: Currently, it isn't. An app simply requests HRTF and the implementation
is responsible for picking one if multiple are available. The idea of
enumerating and selecting from all available HRTFs was considered, but
no design has yet been made.
Q: What is the purpose of alcResetDeviceSOFT?
A: An app will undoubtedly want the ability to enable and disable HRTF at
runtime (e.g. in response to in-game option changes). The usual way of
enabling HRTF would be with the attribute list to alcCreateContext,
however this is clunky if audio playback is already started (either it
would need to destroy the context then create a new one with the new
parameters, or create a context just for the side-effect of changing
the device properties and then not use it for anything). A method just
to reset the device properties seems the most elegant solution, as it
would not interrupt existing contexts, and it would not rely on side-
effects of function behaviors which may not be reliable.
New Procedures and Functions
ALCboolean alcResetDeviceSOFT(ALCdevice *device, const ALCint *attrList);
New Tokens
Accepted as part of the <attrList> parameter of alcCreateContext and
alcDeviceResetSOFT, and as the <paramName> parameter of alcGetIntegerv:
ALC_HRTF_SOFT 0x1992
Accepted as the <paramName> parameter of alcGetIntegerv:
ALC_HRTF_STATUS_SOFT 0x1993
Possible results from a ALC_HRTF_STATUS_SOFT query:
ALC_HRTF_DISABLED_SOFT 0x0000
ALC_HRTF_ENABLED_SOFT 0x0001
ALC_HRTF_DENIED_SOFT 0x0002
ALC_HRTF_REQUIRED_SOFT 0x0003
ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004
ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005
Additions to Specification
Resetting an open device
After a device is opened for playback, an application may reset it to
attempt changing the playback properties. To reset the device, use the
function
ALCboolean alcResetDeviceSOFT(ALCdevice *device, const ALCint *attrList);
The device parameter is a handle to a valid playback device as returned by
alcOpenDevice, otherwise an ALC_INVALID_DEVICE error is generated. The
attrList is the same as what could be passed to alcCreateContext. The AL
is allowed to ignore attribute values and combinations the device cannot
support (e.g. if the device doesn't support the requested ALC_FREQUENCY
value, another frequency value it does support may be set).
On success the function returns ALC_TRUE, and on failure the function
returns ALC_FALSE. Note that a return of ALC_TRUE does not indicate any
attributes were honored, just that the device was successfully reset. If
you need to know what the attributes are after a reset, query the device
using alcGetIntegerv with the relevant attributes.
HRTF mixing
An application may request mixing using a Head-Related Transfer Function,
or HRTF. HRTF can provide better spatial acuity when using headphones by
using special filters designed to replicate how sounds are affected by the
shape of the listener's head as they come in from a given direction. To
request HRTF, specify the ALC_HRTF_SOFT attribute to alcCreateContext or
alcResetDeviceSOFT with the value ALC_TRUE. For example:
ALCint attrs[] = {
ALC_HRTF_SOFT, ALC_TRUE, /* request HRTF */
0 /* end of list */
};
context = alcCreateContext(device, attrs);
Requesting HRTF mixing may cause the AL to reconfigure the device for a
specific output mode and restrict the usable frequency values.
A word of warning: although HRTF can sound great with headphones, it may
result in increased resource usage and it may not sound very good with
ordinary speakers, particularly if the user has surround sound output.
Consequently, it is not a good idea to unconditionally request HRTF
mixing. A good rule of thumb is to not specify an ALC_HRTF_SOFT attribute
by default, letting the AL autoselect it, unless the user indicates
otherwise.
HRTF status query
An easy way to query HRTF status is to simply call alcGetIntegerv with the
ALC_HRTF_SOFT attribute. This will respond with ALC_TRUE if HRTF is in use
on the device, or ALC_FALSE if not.
More detailed status info can be obtained by calling alcGetIntegerv with
the ALC_HRTF_STATUS_SOFT parameter. This may respond with one of the
following values:
ALC_HRTF_DISABLED_SOFT - HRTF is disabled (generic response).
ALC_HRTF_ENABLED_SOFT - HRTF is enabled (generic response).
ALC_HRTF_DENIED_SOFT - HRTF is disabled because it's not allowed on the
device. This may be caused by invalid resource
permissions, or other user configuration that
disallows HRTF.
ALC_HRTF_REQUIRED_SOFT - HRTF is enabled because it must be used on the
device. This may be caused by a device that can
only use HRTF, or other user configuration that
forces HRTF to be used.
ALC_HRTF_HEADPHONES_DETECTED_SOFT - HRTF is enabled because the device
reported headphones.
ALC_HRTF_UNSUPPORTED_FORMAT_SOFT - HRTF is disabled because the device
does not support it with the current
format. Typically this is caused by
non-stereo output or an incompatible
output frequency.
This is not an exhaustive list; extensions may add more status values in
the future, so an application must be prepared to handled unknown
statuses.
Errors
More information about the openal
mailing list