[openal] Trying to implement a linear 1D (left/right) audio balance

Chris Robinson chris.kcat at gmail.com
Mon Apr 21 06:54:11 EDT 2014

On 04/20/2014 05:44 PM, Villermen wrote:
> Basically I'd like to have a balance value of -1f (left channel only) to 1f
> (right channel only) be converted into a position for an OpenAL source
> where it will act as such:
> When having 0f (default value) as balance value both sides (left/right ear)
> should be at 100% gain.
> When 1f 100% for the right ear and 0% for the left ear and the opposite for
> -1f.
> They should attenuate in a linear way.

This isn't really possible with a single source. Although you could use 
the arc method as mentioned in the other message, it won't strictly be 
linear and a center-panned sound won't be 100% on both sides (they'll be 
attenuated slightly to keep the same perceived volume as when panned). 
If that's good enough, though, it's a fine way to handle it.

The most portable way to do what you want, for mono sounds, would be to 
use two sources, one on each side of the listener, and play with their 
gains. For example:

enum { Left=0, Right=1 };
ALuint Source[2];

alGenSources(2, Source);
alSourcei(Source[Left], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(Source[Left], AL_POSITION, -1.0f, 0.0f, 0.0f);
alSourcei(Source[Right], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(Source[Right], AL_POSITION, +1.0f, 0.0f, 0.0f);

// Both sources can use the same buffer, no problem
alSourcei(Source[Left], AL_BUFFER, buffer);
alSourcei(Source[Right], AL_BUFFER, buffer);
// Use alSourcePlayv to make sure they start synchronized
alSourcePlayv(2, Sources);

// Update panning
alSourcef(Source[Left], AL_GAIN, clamp(1.0f-pan, 0.0f, 1.0f));
alSourcef(Source[Right], AL_GAIN, clamp(1.0f+pan, 0.0f, 1.0f));

Alternatively, I could add a panning extension to OpenAL Soft. Though it 
would obviously require a version of OpenAL Soft that supports it for it 
to work.

More information about the openal mailing list