Calling FMOD::Sound::release from a callback

#1

We have a utility that creates a sound, plays it and then releases it when it’s done playing. We’re using an FMOD_CHANNELCONTROL_CHANNEL callback, looking for type FMOD_CHANNELCONTROL_CALLBACK_END. When we get that callback, we’re calling release on our sound object. This seems to cause FMOD to blow up once the callback returns. If i call release on the object outside of the callback, things seem ok.

I could not find anything in the documentation that claims this is dangerous. Can someone positively confirm or deny that calling release from within the callback is a bad idea or is there something else going on here?

NOTE: update() is being called from the main thread.

#2

Currently we would not recommend doing this, although we should at least mention that in the docs.

It does seem like something we possibly do in the future, I have raised this as a task to look into further and determine if it is possible (and something we want to do).

In the meantime we can get the docs updated.

#3

Thanks! Your docs are better than most at answering the weird threading questions that it seems no one else ever documents…but this area seemed to slip through the cracks. :slight_smile:

#4

I got bit by a similar problem and Cameron mentioned similar advice against calling ->release() in a callback and I also noticed as you did, that calling those same FMOD methods in my class/main thread, there was never a problem…only in ->update() which presumably is also run in main thread and any calls it might also make to the static callback would also be in “main” but yet here we are with this problem…a slight mystery and confusion.

I am not an expert on FMOD, so my approach may be unwarranted and/or overkill, but here’s what I did as a strategy to rectify after Cameron advised against calling release() in the callback:

*In my class that performs FMOD, add an array/vector for a small structure to store a little info to later deal with the functions I originally wanted to perform in the callback, with a flag of “what to do” and the FMOD handle to act upon (sound/channel/???).

*Given the docs stating that ->update() and callbacks are performed in the main thread, during update(), yet ->release() still caused some sort of problem, I was still worried the callbacks were somehow using another thread to deal with some stuff within FMOD, so also created a CriticalSection. Again, probably not necessary, but I was “scared” and did so anyway, because I’m possibly ignorant of how it works :slight_smile:

*Create a static pointer to my class on instantiate (nulled during my class destruction)

*In the static call back, enter critical, update the array/vector (my static class pointer gives me access to method/member) with a new element containing the flag of “what to do,” and the handle of sound/channel, exit critical.

*In my class, the same place I call ->update(), add a call to a new method that deals with the array/vector elements left over from any FMOD callback entries that were created.

*In this new method, loop through array/vector within which I:
enter crit,
assign flag/handle from structure to local vars,
delete that array element,
exit crit,
deal with the “what to do” cases from the local vars (releases, other FMOD calls upon channel/sound handle, etc.)
continue loop until empty

Not sure all of this was necessary, but works without problem now