[Openal-devel] Extension proposal
Chris Robinson
chris.kcat at gmail.com
Tue Sep 16 05:34:42 PDT 2008
Here's a proposal for a new distance model. I came up with it while trying to
modify an advanced Doom port to use OpenAL. An issue I ran into was that the
game uses a lookup table to provide attenuation values, and attempts to
replicate it using existing models has been somewhat fruitless. It would also
run into further issues for any mods that may have provided its own table.
I realize this is largely to "emulate" custom sound systems used by old
programs. However, with them being/becoming open source, updating them to use
newer and more robust APIs (such as OpenAL) is a typical goal. Being able to
provide what they need without having to resort to hacks would make it more
enticing to prospective developers.
The only other option would be to provide a callback, or similar method.. but
that's not really OpenAL's style. I could imagine some sort of "parameter
program" extension doing this better, but the needed ground work just isn't
there yet. And it's definitely not something I could come up with in a
reasonable time frame.
Name
EXT_attenuation_table
Name Strings
AL_EXT_attenuation_table
Version
1.0
Number
??
Overview
This extension provides support for custom rolloffs. It allows
applications to provide an array of gains which would be used in place of
normal attenuation algorithms. This could be useful, for example, for
rolloffs that existing distance models can't emulate or that would be too
processor intensive for a target system.
Issues
Q: Should the table be per source or per context?
A: Per context. Being per source could add a measurable memory footprint
if the application uses a lot of sources and/or large tables. Most uses
would likely have all sources using the same table, which would create
a needless amount of memory use. Though per source rolloffs could have
some use, this wouldn't be the appropriate place to add it.
New Procedures and Functions
void alAttenuationTableEXT(Aenum target, ALsizei size, ALfloat *table);
New Tokens
Accepted by the <modelName> parameter of alDistanceModel, the <paramName>
parameter of alGetFloatv, and the <target> parameter of
alAttenuationTableEXT:
AL_ATTENUATION_TABLE_EXT 0xD010
Accepted by the <paramName> parameter of alGetInteger and alGetIntegerv:
AL_ATTENUATION_TABLE_SIZE_EXT 0xC010
Additions to Specification
The function
void alAttenuationTableEXT(Aenum target, ALsizei size,
ALfloat *table);
can be used to specify an attenuation table for the current context.
<target> must be AL_ATTENUATION_TABLE_EXT. An array of <size> ALfloats is
passed through the <table> parameter, which can then be used as a lookup
table by the Attenuation Table distance model. The value of <table> is
ignored if <size> is 0.
After specifying an attenuation table, any previous table for the target
is discarded. Passing 0 for <size> effectively deletes the attenuation
table. The error AL_INVALID_OPERATION is generated if an attempt is made
to delete an attenuation table while it's in use. Changing the table while
it's in use is not an error, and the change will take effect at the next
update.
The value AL_ATTENUATION_TABLE_EXT may be passed to alDistanceModel to
enable attenuation according to the attenuation table. Under this model,
the calculated distance is clamped as if AL_LINEAR_DISTANCE_CLAMPED was
used. The gain is then computed by:
entry = AL_ROLLOFF_FACTOR * (distance–AL_REFERENCE_DISTANCE) /
(AL_MAX_DISTANCE–AL_REFERENCE_DISTANCE) *
(AL_ATTENUATION_TABLE_SIZE_EXT-1)
gain = AttenuationTable[entry]
If AL_MAX_DISTANCE is the same as AL_REFERENCE_DISTANCE, which would
normally cause a divide-by-0, the first entry of the table is used.
Attempting to enable the Attenuation Table distance model while no table
is specified results in an AL_INVALID_OPERATION error.
To retrieve the current attenuation table, first query its size by calling
alGetInteger or alGetIntegerv using AL_ATTENUATION_TABLE_SIZE_EXT:
ALint tableSize = alGetInteger(AL_ATTENUATION_TABLE_SIZE_EXT);
/* or */
ALint tableSize;
alGetIntegerv(AL_ATTENUATION_TABLE_SIZE_EXT, &tableSize);
The returned value is the number of ALfloat values in the current table,
and the number of entries required for the storage array. Retrieve the
table using alGetFloatv:
ALfloat *table = malloc(tableSize * sizeof(ALfloat));
alGetFloatv(AL_ATTENUATION_TABLE_EXT, table);
Attempting to retrieve a table after it's deleted or before it's set is a
valid no-op.
Errors
The error AL_INVALID_OPERATION is generated if alAttenuationTableEXT is
called with a value of 0 passed to <size>, while the target is in use.
The error AL_INVALID_OPERATION is generated if alDistanceModel is called
with AL_ATTENUATION_TABLE_EXT, while no attenuation table is set.
More information about the Openal-devel
mailing list