Thanks for your reply jeff.
I am creating an event instance every time I try to play a sound by calling RuntimeManager.CreateInstance
. I highly doubt that is the issue because the same code works for the longer sounds without causing the error (true in all cases, more on that below). Posting the entire class for more clarity:
public class SoundEventTrigger : MonoBehaviour
{
public FMODUnity.EventReference eventReference;
private FMOD.Studio.EVENT_CALLBACK eventCallback;
private FMOD.Studio.EventInstance currentInstance;
private void Start()
{
eventCallback = new FMOD.Studio.EVENT_CALLBACK(SoundEventCallback);
}
public void PlaySound()
{
var eventInstance = FMODUnity.RuntimeManager.CreateInstance(eventReference);
currentInstance = eventInstance;
eventInstance.setCallback(eventCallback);
eventInstance.start();
}
public void StopSound()
{
currentInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
}
[AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
private static FMOD.RESULT SoundEventCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
{
FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);
switch (type)
{
case FMOD.Studio.EVENT_CALLBACK_TYPE.SOUND_STOPPED:
{
var sound = new FMOD.Sound(parameterPtr);
var result = sound.release();
sound.clearHandle();
result = instance.release();
instance.clearHandle();
break;
}
}
return FMOD.RESULT.OK;
}
}
As I mentioned, this works with the longer sounds, except when I try to create more than one event instance at a time. If one instance is stopped or finishes playing while there are other instances playing the same sound, it will correctly stop them due to the sound being released. But for some reason, despite the callback being called for all of them, this will not release the sound until the moment all of them would have finished playing naturally. If I try to start a new instance during this delay it results in the invalid handle error but if I wait for when the sound is actually released it works fine.
This is highlighted by the log messages where I call for release on the first instance, which results in OK result code. This is immediately followed by the handler being called for all the other instances where releasing the sound gives the invalid handle error since it has already been released (this has no negative impact on the game itself) followed by the log message: [FMOD] SoundI::release : <audio_file's_name> (000001617D5D39B8)
. After the delay the log message [FMOD] SoundI::release : (00000163DF98A378)
appears, highlighting that the sound has actually been released. If there is only one instance at a time, the second message follows immediately after the first one.
This probably isn’t that big of a deal since either we will play unique sounds and for effects that play the same sounds I will have to build some sort of management system to control when a sound should be released by checking how many instances are using the given sound.
I used the log messages generated by the FMOD Unity Integration that are generated after setting the Logging Level to Log in the FMOD Settings. I double-checked this by using the FMOD Studio’s profiler and monitoring the RAM usage it displays. I will try to describe all four cases in detail:
- Using FMOD Studio Event Emitter
- Shorter sound
According to the logs, the sound is not released when it finishes playing, neither when it gets stopped. This is confirmed by the fact that when I play it again there are no calls to create the sound. Profiler shows the memory not returning to the previous levels which confirms this.
- Longer sound
When the sound naturally finishes it is not released until the moment I try to play it again. At that point it for some reason releases the sound and loads it back into memory within the same frame (the profiler literally says so). When the sound gets stopped the emitter acts as expected and the sound is immediately released. Memory usage confirms both cases.
- Using the API (above code)
- Shorter sound
Letting the sound play out or stopping it ends up in a call to release the sound but the second log message never appears. Trying to play the sound again results in the invalid handle error popping up every frame. In memory there is a slight decrease in used memory but it does not go back to the initial level.
- Longer sound
Either playing out or stopping the sound results in the sound being released (outside the already mentioned issue with multiple concurrent instances) as confirmed by the profiler.
I think the issue with the multiple instances is something I will have to manage on our side anyway, so I am not particularly concerned with that. The emitter has a weird behaviour but there might be a design decision behind that. Although not releasing the sound and then doing so just to load it back in again is weird. As for the API, I am still not sure what I could be doing wrong. It’s almost like some part of FMOD just refuses to release the shorter sound but another part thinks it just did so and in the end it tries to use the old handle that is somehow no longer valid?
The event I am using is Oneshot, its master track has persistence set to off and it contains just one single instrument with the given sound. This event is in a bank that doesn’t have sample data preloaded, so I would expect FMOD to release the sound, at least when I use the API.