OgreAL r130

Phobius

16-07-2009 12:00:19

  1. Bug Fix: OgreAL Listener (not yet fully implemented) was not being exported as a symbol to DLL.[/*:m]
  2. Feature Added: Library users now have the ability to check fade state and cancel a fade in the middle of its operation if so desired.[/*:m]
  3. Bug Fix: Sources were not being released after a sound had finished playing naturally. By naturally, it is meant that OpenAL set the state to AL_STOPPED after the sound file ended. All sources are now released, whether by natural stop or manual stop().[/*:m][/list:u]

cycheng

08-08-2009 09:15:37

Hi, I am a new comer of OgreAL, I use OgreAL in my project, and saving me a lot of time :)
thanks everyone contribute to this system!

I download r128 (few weeks ago), and do a little modify, because in r128 I run "ManySources_Demo" and I got crash when exit the demo, it seems OpenAL delete un-exist source. My solution is :


// in OgreALSoundManager.cpp
SourceRef SoundManager::_requestSource(Sound *sound) {
...;
else if(!mActiveSounds.empty())
{
...;
if( sound->getPriority() > activeSound->getPriority() ||
sound->getPriority() == activeSound->getPriority() && distSound < distActiveSound )
{
// cycheng, activeSound will become non-active, so release its source
[b]activeSound->setSource( AL_NONE ); [/b]


// And I add some check :
SourceRef SoundManager::_releaseSource(Sound *sound) {
...;
// cycheng, if this source is put in "mQueuedSounds" (soundFound == false),
// then its source must be AL_NONE
#if OGRE_DEBUG_MODE
if( !soundFound )
assert( source == AL_NONE );
#endif

if( source != AL_NONE ) {
...;
if( !mQueuedSounds.empty() ) {
...;
// cycheng, it is not allowed that active sounds amount greater than
// hardware cability (mMaxNumSources, determined in createSourcePool() )
assert( static_cast< int >( mActiveSounds.size() ) <= mMaxNumSources );
}

// in OgreALSound.cpp
bool Sound::updateSound() {
...;
if(mSource != AL_NONE) {
if( ... ) { ...; }
if( ... ) { ...; }
for( ... ) { ...; }
// Done with these comparisons. Last offset becomes current for next frame.
mPreviousOffset = currOffset;

// cycheng, because there is possible call Sound::stop() in mFinishedCallback, so
// checking if the mSource become invalid
if( mSource == AL_NONE )
return true;
...;

But here I notice that in r130 has made change, when it is "isStopped() && !mManualStop",
it will return true after call mFinishedCallback, so my modification could be ignore.



I have no idea if these modification are suitable, so I just provide some opinions :wink:

And I also add some utility function :

/** specify an increase volume velocity, e.g. 0.1 means every second increase 0.1 volume (or gain)
@param increaseVelocity = delta_gain/sec ( In second )
*/
bool Sound::fadeInByVelocity( Ogre::Real increaseVelocity ) {
// by cycheng
if( isPlaying() &&
mGain != mMaxGain &&
(mFadeMode == FADE_NONE || mFadeMode == FADE_OUT))
{
// Swap fade direction.
mFadeMode = FADE_IN;
// time = dist/velocity
mFadeTime = (mMaxGain - mMinGain) / increaseVelocity;
mRunning = (mGain - mMinGain) / increaseVelocity;
}
else {
mFadeMode = FADE_IN;
mFadeTime = (mMaxGain - mMinGain) / increaseVelocity;
mRunning = 0.0;
setGain(mMinGain);
return play();
}
return true;
}

/** just like fadeInByVelocity
@param increaseVelocity = delta_gain/s ( In second ) */
bool Sound::fadeOutByVelocity( Ogre::Real decreaseVelocity ) {
if( isPlaying() &&
mGain != mMinGain &&
(mFadeMode == FADE_NONE || mFadeMode == FADE_IN))
{
// Swap fade direction.
mFadeMode = FADE_OUT;
// Construct fadeTime and running times so that they interpolate nicely
// across the supplied time interval. This time we go from B to A.
mFadeTime = (mMaxGain - mMinGain) / decreaseVelocity;
mRunning = (mMaxGain - mGain) / decreaseVelocity;
return true;
}
return false;
}


And some unimportant modification :

// in OgreALSoundManager.h
class OgreAL_Export SoundManager {
private:
// cycheng :
bool mIsActiveSorted; // is active sound list sorted ?
bool mIsQueueSorted; // is queue sound list sorted ?

// serious utility for making sure sound list is sorting well
void sortActiveSounds();
void sortQueueSounds();
void lockActiveSounds();
void unlockActiveSounds();
void lockQueueSounds();
void unlockQueueSounds();

// I add some comments
SoundList mActiveSounds; // currently active sounds, be sorted from low priority to high priority
SoundList mQueuedSounds; // dis-active sounds, be sorted from high priority to low priority
...;
};

// in OgreALSoundManager.cpp
void SoundManager::sortActiveSounds() {
lockActiveSounds();
std::sort(mActiveSounds.begin(), mActiveSounds.end(), SortLowToHigh());
mIsActiveSorted = true;
unlockActiveSounds();
}

void SoundManager::sortQueueSounds() {
lockQueueSounds();
std::sort(mQueuedSounds.begin(), mQueuedSounds.end(), SortHighToLow());
mIsQueueSorted = true;
unlockQueueSounds();
}

void SoundManager::lockActiveSounds() {
for( size_t i = 0; i < mActiveSounds.size(); i++ )
mActiveSounds[ i ]->setStateCached( true );
}

void SoundManager::unlockActiveSounds() {
for( size_t i = 0; i < mActiveSounds.size(); i++ )
mActiveSounds[ i ]->setStateCached( false );
}

void SoundManager::lockQueueSounds() {
for( size_t i = 0; i < mQueuedSounds.size(); i++ )
mQueuedSounds[ i ]->setStateCached( true );
}

void SoundManager::unlockQueueSounds() {
for( size_t i = 0; i < mQueuedSounds.size(); i++ )
mQueuedSounds[ i ]->setStateCached( false );
}

void SoundManager::insertToActiveSound( Sound *sound ) {
// cycheng, it is not allowed that active sounds amount greater than
// hardware cability (mMaxNumSources, determined in createSourcePool() )
assert( static_cast< int >( mActiveSounds.size() ) < mMaxNumSources );

if( mIsActiveSorted ) {
SortLowToHigh cmpFunc;
// insert to proper place
size_t i;
for( i = 0; i < mActiveSounds.size(); i++ )
// if sound's priority < mActiveSounds[ i ]'s priority ?
if( cmpFunc( sound, mActiveSounds[ i ] ) )
break;

mActiveSounds.insert( mActiveSounds.begin() + i, sound );
}
else {
mActiveSounds.push_back(sound);
sortActiveSounds();
}
}

void SoundManager::insertToQueueSound( Sound *sound ) {
assert( sound->getSource() == NULL );
if( mIsQueueSorted ) {
SortHighToLow cmpFunc;
// insert to proper place
size_t i;
for( i = 0; i < mQueuedSounds.size(); i++ )
// if sound's priority > mQueuedSounds[ i ]'s priority ?
if( cmpFunc( sound, mQueuedSounds[ i ] ) )
break;

mQueuedSounds.insert( mQueuedSounds.begin() + i, sound );
}
else {
mQueuedSounds.push_back(sound);
sortQueueSounds();
}
}


Relative modification :

// replace mActiveSounds/mQueuedSounds.push_back(sound); to
// insertToActiveSound/insertToQueueSound
SourceRef SoundManager::_requestSource(Sound *sound) {
...;
if(!mSourcePool.empty())
{
//mActiveSounds.push_back(sound);
insertToActiveSound( sound ); // cycheng
...;
return source;
}
else if(!mActiveSounds.empty())
{
// cycheng, sort it before we use
if( ! mIsActiveSorted )
sortActiveSounds();
...;
if( sound->getPriority() > activeSound->getPriority() ||
sound->getPriority() == activeSound->getPriority() && distSound < distActiveSound )
{
...;
insertToActiveSound( sound );
insertToQueueSound( activeSound );

//mQueuedSounds.push_back(activeSound);
//mActiveSounds.push_back(sound);
}
else
{
insertToQueueSound(sound); // cycheng
//mQueuedSounds.push_back(sound);
return AL_NONE;
}

void SoundManager::updateSounds() {
...;
/*for(SoundMap::iterator i = mSoundMap.begin(); i != mSoundMap.end(); ++i) {
i->second->setStateCached(true);
}
// Sort the active and queued sounds
std::sort(mActiveSounds.begin(), mActiveSounds.end(), SortLowToHigh());
std::sort(mQueuedSounds.begin(), mQueuedSounds.end(), SortHighToLow());
// Revert back to live states.
for(SoundMap::iterator i = mSoundMap.begin(); i != mSoundMap.end(); ++i) {
i->second->setStateCached(false);
}*/
// cycheng
if( ! mIsActiveSorted ) sortActiveSounds();
if( ! mIsQueueSorted ) sortQueueSounds();


void SoundManager::updateSourceAllocations()
{
while(!mQueuedSounds.empty() && !mActiveSounds.empty())
{
...;
if( queuedSound->getPriority() > activeSound->getPriority() ||
queuedSound->getPriority() == activeSound->getPriority() &&
distQueuedSound < distActiveSound )
{
...;
// cycheng, we do not sure if queuedSound and activeSound be inserted into correct
// place, so set flag to false
mIsActiveSorted = false;
mIsQueueSorted = false;
}

// in OgreALSound.cpp
bool Sound::fadeIn(Ogre::Real fadeTime) {
// add a comment
// mFadeTime = A to C
// ..



I also change header include, to prevent include "Ogre.h"


// in OgreALPrereqs.h
#include "OgrePrerequisites.h" // instead of Ogre.h

// and I add a Memory Allocate Configuration
typedef Ogre::GeneralAllocatedObject SoundAlloc;

// in OgreALSoundManager.h
#include "OgreException.h"
#include "OgreIteratorWrappers.h"
#include "OgreString.h"
#include "OgreFrameListener.h"

//#include "OgreALListener.h" - comment by cycheng
//#include "OgreALSound.h"
#include "OgreALPrereqs.h"

// in OgreALListener.h
#include "OgreALPrereqs.h"
#include "OgreMovableObject.h"
#include "OgreSingleton.h"

// in OgreALSound.h
#include "OgreALPrereqs.h"
#include "OgreALMemberFunctionPointer.h"
#include "OgreMovableObject.h"


That's all!
Thanks for your patience to read!

cycheng