# OpenAL - sound transition to loop

## Recommended Posts

Doggan    528
I am using OpenAL. I have a motor I am trying to simulate. I have 3 files: motorStart.wav, motorRun.wav, and motorShutdown.wav. The motor can be turned on and off by the user. When the user turns the motor on, I want motorStart.wav to play. As soon as that ends, I want motorRun.wav to loop forever, until the user turns the engine off, at which point I want motorShutdown.wav to play. The shutting off I have. If motorRun.wav is looping, I just call alSourceStop( motorRun ) and then alSourcePlay( motorShutdown ). How can I get the turning on to transition smoothly, so that motorRun will be looping forever as soon as motorStart.wav finishes? I looked into alSourceQueueBuffers() but I cannot have motorRun.wav loop continue to loop with that method. Putting them into a single source won't work either since one will loopback and the other won't. Any help is appreciated. Thanks.

##### Share on other sites
Drew_Benton    1861
I think the best way is though setting up a harcoded class state system to track what needs to be played when. For example, what you want to do is start of by playing the Start sound. Howeverm you want the run sound to also start playing at the near end of that sound, so it resembles a real motor. Finally when you kill the motor, the running sound should trial off as the end sound plays.

I don't have any code for this, but here's the general idea using C++ and pseudo code:

class Motor{   int state = -1;   void Start()   {      state = 0;   }   void Update()   {      if( state == 0 )      {         static bool played = 0;         if( !played )         {             Play StartMotor            StartMotor looping = false;            played = 1;         }         static int timepos = 0;         timepos += timesincelastframe;         if( timepos >= 7/8's of total StartMotor.wav )         {            state = 1;         }      }      else if( state >= 1 )      {         static bool played = 0;         if( !played )         {            RunMotor looping = true;            played = 1;            Play RunMotor;         }         static int timepos = 0;         timepos += timesincelastframe;         if( state == 2 )         {            RunMotor looping = false;            static bool played = 0;            if( !played )            {               Play StopMotor;               StopMotor looping = false;               played = 1;            }            RunMotor Gain -= SofteningFactor            if( StopMotor state == AL_STOPPED )                 state = -1;         }      }   }   void Stop()   {      state = 2;   }};

You will always call Motor.Update in your update function. When the motor is to be startd, you call the .Start, then when they want to stop, they call the .Stop function.

So what you will need OpenAL wise is:
- 3 total sources, one for each buffer- alSourcePlay(Source); to play the source- alSourcef ( Source, AL_GAIN, Value ); to lower the gain for the motor runnign when it starts to die out, Value should start at one then go to 0- alSourcei (Source, AL_LOOPING,  AL_TRUE  ); to set the looping to True or False for each respective source- ALenum state;  alGetSourcei(source, AL_SOURCE_STATE, &state);  (state == AL_STOPPED); to finally close everything down at the end- Then something like GetTickCount or some other timer to know how much time has passed for smooth transitions.- You can hard code in the length of the sounds since you have them. Finding the length I think is not that hard with wavs, I just don't remember how to do it off the top of my head.

And I think that covers most of it. I may have missed a few things though, so you can point those out. Also take a look at the DevMaster OpenAL tutorials for other ideas of doing some stuff. If you have any questions about this ask away! Good luck! [smile]

##### Share on other sites
Doggan    528
Great, thanks a lot Drew.

I implemented something similar to your idea for start up to running transition. A few changes to your idea (noteably changing the 'else if' to an 'if' so it doesn't wait an entire cycle, changing the 7/8 to 1.0, and actually stopping the start sound when this condition is met). I kept the running to shut down transition as I had it.

This idea your presented had crossed my mind, but I /thought/ that OpenAL might have something a little more robust already built into it to allow for this. I'll think about the design for a little while, but this is good enough for now. Thanks again :)

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account