Stopping an event after fade completion?

I’m currently working on trying to get our game to transition more smoothly between music, rather than abruptly stopping and then starting the next track. I’ve been able to get the current track fading out nicely using fade points, but the issue I’m having is that I’m not sure exactly when to actually call stop & delete the old event and start the next queued one. The event remains in the “playing” playback state even when the volume hits 0, which I would expect, but is there any way of knowing that the fade has completed?

Snippet from fading out the music via the fade points:

            ulong dspClock;
            ulong parentClock;
            result = eventSet.FMODEvent.getChannelGroup(out group);
            result = group.getDSPClock(out dspClock, out parentClock);

            FMOD.System system;
            FMOD.SPEAKERMODE mode;
            int numSpeakers;
            studioSystem.getLowLevelSystem(out system);
            system.getSoftwareFormat(out _SampleRate, out mode, out numSpeakers);

            const float fadeTime = 1.0f;
            ulong fadedTime = dspClock + Convert.ToUInt64(fadeTime * _SampleRate);

            group.addFadePoint(dspClock, fadeTime);
            group.addFadePoint(fadedTime, 0.0f);

After an event gets a volume of 0 it will go “virtual”, which should trigger a REAL_TO_VIRTUAL callback, and from there you should be able to stop and release the event.
We have a C# example that shows how to set a callback on an event if you are unsure how to go about doing that. You will need to set the VOL0_BECOMES_VIRTUAL flag when initializing the Studio system.
EDIT: On a side note, you shouldn’t need to set fade outs if using FMOD Studio API. Instead you can add an AHDSR to the event master track volume, that way when the event is stopped the release time will fade out when the track automatically.

Thanks for the response! I’ll pass the AHDSR information along to our audio guy to take a look there and we can hopefully go that route. Judging from your response and the documentation, the fadeout should happen automatically when calling stop on the event instance as long as STOP_MODE.IMMEDIATE is not passed, correct?

As far as the REAL_TO_VIRTUAL, I don’t seem to be getting that callback. I’m passing the flag as follows during initialization:

const int maxChannels = 1000;
studioSystem.initialize( maxChannels, FMOD.Studio.INITFLAGS.SYNCHRONOUS_UPDATE, FMOD.INITFLAGS.VOL0_BECOMES_VIRTUAL, IntPtr.Zero );

And I’m registering for callbacks when I create an event instance as follows:

FMOD.Studio.EventInstance gameEvent;

result = _event.createInstance( out gameEvent );
Debug.Assert( result == FMOD.RESULT.OK );

result = gameEvent.setCallback( _EventCallback, EVENT_CALLBACK_TYPE.ALL );

I’m getting other EVENT_CALLBACK_TYPE just as started, stopped, etc. However, I’m not gettingthe REAL_TO_VIRTUAL one. Is there anything else that needs set besides the initialization flag and the callback on the event instance?

Correct, as long as it has been initialized correctly, which it looks like it has.

That should be triggering the callback, what version of FMOD are you using?