OpenAL problem - changing gain of source
Asked Answered
V

1

3

I've recently been working on porting my game to be cross-platform, and decided to go with OpenAL for my cross-platform audio engine.

I have 16 "channels" (OpenAL sources) for playing up to 16 sounds concurrently. To play a sound, I switch which buffer is linked to a given source, and also set the gain, source position, and so on in order to play a sound in a given "channel" (source).

The problem is, I've noticed that my "gain" settings do not seem to have immediate effect. For instance, if a loud "lightning" sound plays in a given source at 0.5 gain, then when I have a button click sound play at 0.15 gain later, this click starts off FAR too loud. Then, each subsequent time it is played, the volume decreases until around the 3rd or 4th click it sounds like it's around the proper 0.15 gain.

The first button click is barely audible, and it seems to ramp up in volume until it reaches the 0.15 gain.

So in short, a "source" seems to be remembering the former gain settings, even though I am resetting those before playing a new sound in the same source! Is this a bug? Or something I don't understand about OpenAL? How can I get it to "instantly" change to the new gain/position settings?

Relevant code to play a sound:

[Channel is a value between 0 and 15, soundID is a valid index into the gBuffer array, stereoPosition is an integer between -255 and 255, and volume is between 0 and 255. This is from a function that's a wrapper for my game that used to use values between 0-255, so it converts the values to proper OpenAL values.]

    // Stop any sound currently playing in this channel ("source")
alSourceStop( gSource[channel] );

    // What sound effect ("buffer") is currently linked with this channel? (Even if not currently playing)
alGetSourcei( gSource[channel], AL_BUFFER, &curBuffer );

    // attach a different buffer (sound effect) to the source (channel) only if it's different than the previously-attached one.
    // (Avoid error code by changing it only if it's different)
if (curBuffer != gBuffer[soundID])  
    alSourcei( gSource[channel], AL_BUFFER, gBuffer[soundID] );

    // Loop the sound?
alSourcei( gSource[channel], AL_LOOPING, (loopType == kLoopForever)  );

    // For OpenAL, we do this BEFORE starting the sound effect, to avoid sudden changes a split second after it starts!
volume = (volume / 2) + 1;  // Convert from 0-255 to 0-128

{
    float sourcePos[3] = {(float)stereoPosition / 50, 0.0, 2.0};

        // Set Source Position
    alSourcefv( gSource[channelNum], AL_POSITION, sourcePos );  // fv = float vector

        // Set source volume
    alSourcef( gSource[channelNum], AL_GAIN, (float)newVolume / 255 );
}

    // Start playing the sound!
alSourcePlay( gSource[channel] );

I can post setup code too if desired, but nothing fancy there. Just calling

alSourcef( gSource[n], AL_REFERENCE_DISTANCE, 5.0f );

for each source.

Varietal answered 5/8, 2011 at 18:8 Comment(8)
I've done more testing this, and it's better explained like so: 1) Play a sound in an OpenAL source at a high gain, like 1.0. 2) Once the sound has finished playing, play a different sound in any source at a very low gain, like 0.01. The new sound will not play at the specific 0.01 gain, but will rather start at the 1.0 gain and "slide down" to the proper gain setting. For very short sounds, like button clicks, this results in the next several click sounds coming out at, say, 1.0, 0.7, 0.4, and finally 0.01 gains. (These values are estimates of what it sounds like to my ear.)Varietal
This is on MacOS X 10.6.8. I've not checked to see if it happens on other OSes. I can easily modify Apple's own OpenAlExample that comes in /Developer/ to repeat the same behavior.Varietal
I've experienced this too and would like to know how to address it.Rhu
I eventually contacted Apple about it, and they told me this is a known but in their OpenAL implementation on OS X 10.6 that will not be fixed. It is fixed in OS X 10.7 and on iPhone.Varietal
have you found a workaround to this?Artisan
Glaiel -- the "workaround" is to use something other than OpenAL on OS X 10.6 or earlier, since Apple is not going to fix it in their implementation on this OS. For my game, I switched to irrKlang or SDL_Mixer depending on the platform.Varietal
I'm finding that the problem still exists on iOS 5.1 and Mac OS X 10.7.4. Apple don't seem to have fixed it.Brannon
If it affects you, I'd file a bug report. I've since moved on.Varietal
K
0

We just faced the same problem when setting the ByteOffset for seeking to a position in a sample and found now the solution to get it working:

Just always delete and recreate the source before setting any parameter on it.

So if you want to change the gain and/or other parameters:

  • OpenAL.AL.DeleteSource(oldSourceID);
  • newSourceId = OpenAL.AL.GenSource();
  • OpenAL.AL.Source(newSourceId , OpenTK.Audio.OpenAL.ALSourcef.Gain, yourVolume);
  • OpenAL.AL.Source(newSourceId , OpenTK.Audio.OpenAL.ALSourcef.xxx, yourOtherParameter);

Hope it works for you and finally have a workaround after 10 years :-)

Kiwanis answered 9/12, 2021 at 10:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.