[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