[openal] Porting from XAudio2 to OpenAL - few questions

Chris Robinson chris.kcat at gmail.com
Wed Mar 26 05:06:07 EDT 2014


On 03/25/2014 09:32 AM, Mariusz 'MX' Szaflik wrote:
> ***HERE*** -- matrix [NumberOfChannelsInSource x NumberOfChannelsInOutput]
> two sets of float[a x b] one for multiplying each element of original
> matryx and one for adding to the result

The main problem there is that OpenAL is purposely designed to hide the 
number of output channels, and its configuration. OpenAL virtualizes 
sound positions so it will work regardless of whatever standard or 
exotic setup a user may have now or in the future. Apps just place 
sounds somewhere and OpenAL will do the best it can to "render" it in 
that position, regardless if it's using stereo, 3-channel, 2.1, 5.1, 
7.1, etc... or even things like HRTF, which is really only stereo but 
provides for dozens of distinct points around the listener.


There's a few things I can think of to do for an extension to provide 
more per-channel control with multi-channel buffers, and I'm CC'ing the 
list in hopes of getting more feedback.


One idea is to be able to set angles and gains for each buffer channel 
on a source, with the number of angles and gains dependent on the buffer 
format. For example, to load a 5.1 buffer, and rotate it 90 degrees 
around the listener:

alBufferData(buffer, AL_FORMAT_51CHN16, ...);
alSourcei(source, AL_BUFFER, buffer);
ALint angles[6] = { // buffer is 5.1, so there's 6 channels
     -30 + 90, // front left
      30 + 90, // front right
       0 + 90, // front center
            0, // lfe (angle ignored, always goes to the lfe output
               //      if preset)
    -110 + 90, // back left
     110 + 90  // back right
};
alSourceiv(source, AL_MC_ANGLES, angles);

And with a stereo buffer, reducing the gain of the right channel by half 
and leaving the left gain at full:

alBufferData(buffer, AL_FORMAT_STEREO16, ...);
alSourcei(source, AL_BUFFER, buffer);
// buffer is stereo, so there's 2 channels
ALfloat gains[2] = { 1.0f, 0.5f };
alSourceiv(source, AL_MC_GAINS, gains);


Another idea is similar to the above, except instead of setting angles 
and gains for each channel, you set a (source relative) position and 
OpenAL's distance attenuation and panning rules would apply -- with an 
exception for LFE, which would distance attenuate but not pan. However, 
at this point it really feels like you just want to manipulate discrete 
sources.


And that brings me to a third idea. The ability to have multiple sources 
sharing a single multi-channel buffer, and each source acting as a 3D 
mono source using only one of the buffer channels. So for instance, say 
you have a stereo buffer and two sources. You could assign the same 
buffer to each source, and specify that each source would... well, 
source from the left or right buffer channel. e.g.

alBufferData(buffer, AL_FORMAT_STEREO16, ...);

alSourcei(sources[0], AL_BUFFER, buffer);
alSourcei(sources[0], AL_CHANNEL_SOURCE, AL_FRONT_LEFT);

alSourcei(sources[1], AL_BUFFER, buffer);
alSourcei(sources[1], AL_CHANNEL_SOURCE, AL_FRONT_RIGHT);

alSourcePlayv(2, sources);

Then move the sources around, use cones, whatever... treat them as if 
they were they were mono. The only practical difference from a mono 
source is that source[0] would be playing the buffer's left channel, and 
source[1] would be playing the buffer's right channel. The one caveat 
here would be that a source using the LFE channel would only ever mix to 
an LFE output, but would otherwise act like a mono source (attenuate 
with distance, be occluded by a cone, etc).

If a channel source is specified that doesn't exist in the buffer, the 
source is silent. Setting the channel source to AL_NONE would revert 
back to normal behavior.


Of the three options, I think the 3rd is the sanest. Although the first 
two would work, they feel rather messy with the buffer format 
determining how many elements get read or written, and resetting it back 
to defaults wouldn't quite be that straight forward either. But I also 
recognize that the third option puts a bit more work on the application 
to manage multiple sources.


More information about the openal mailing list