[SOLVED] Lots of missing meta-data when reusing sound file

shenjoku

02-01-2014 20:49:53

I'm trying to figure out how to setup a sound effects system, and as such it is a requirement to be able to play multiple instances of the same sound file. Currently I have code like the following to test this feature:
fFirst = sm->createSound("first", "bells004.wav", false, true, false, nullptr, true);
fSecond = sm->createSound("second", "bells004.wav", false, true, false, nullptr, true);

fFirst->setListener(this);
fFirst->play();
fSecond->setListener(this);
fSecond->play(true);

// Causes an infinite loop.
fSecond->setPlayPosition(2.0f);


I'm running into a problem when calling setPlayPosition() where it will infinite loop in the code that is trying to make sure you aren't specifying a position out of the possible play range that looks like the following:
// Wrap time
if ( seconds > mPlayTime )
{
do { seconds-=mPlayTime; }
while ( seconds>mPlayTime );
}


It's infinite looping because mPlayTime is 0.0. This is due to the fact that when loading the second sound it calls a different _openImpl() that does not bother storing any of the important meta-data about the sound file just because it's reusing the previously loaded buffer. There are probably other things that don't work as well, but this is all I have tested so far.

As to how to fix this I'm not entirely sure. It seems to me that both _openImpl() functions need to populate the meta-data somehow. The only thing I can think of is to somehow get a pointer to the OgreOggISound that the original sound buffer was loaded into and copy all of its information into the new instance. If there's some way to get the file stream and just do everything the other _openImpl() is doing except for creating the AL buffer then that could work too.

Thoughts?

stickymango

06-01-2014 17:22:00

I've reworked the code to initialise the necessary variables when sharing buffers, use latest SVN.

shenjoku

06-01-2014 23:53:55

There's a crash with this change. The calls to _registerSharedBuffer() are missing the third parameter. Looks like it should be passing this.

EDIT: There's a crash that happens sometimes due to the mBuffers memory getting freed by all of the OgreOggISound objects that are supposed to be sharing it. It's also causing memory leaks since the mBuffers being allocated in the constructor is being overwritten when _setSharedProperties() is called without being deallocated. Both of these problems can be easily fixed if mBuffers was made to use something like std::shared_ptr. I'm pretty sure there's an Ogre::SharedPtr or something that would probably work for this.

EDIT2: I've made the necessary changes and uploaded a new patch to mediafire. I changed mBuffers to Ogre::SharedPtr<std::vector<ALuint>>, which will handle managing the deletion of the memory once all OgreOggISound objects are no longer using it. I wasn't sure exactly how to allocate the std::vector<ALuint> objects though, so I just used new. Feel free to change it however you need to make it work for you.

shenjoku

09-01-2014 01:24:32

Looks like this is all fixed :)

stickymango

09-01-2014 09:58:39

Great :)