[iOS] Certain WAV files triggering channel end callback prematurely.

This sound created with Adobe Audition CC - https://dl.dropboxusercontent.com/u/3571256/test-sound.wav will trigger FMOD_CHANNELCONTROL_CALLBACK_END twice. Once immediately on playback and then a second time when the sound ends.

Expectation would be FMOD_CHANNELCONTROL_CALLBACK_END is only called when the sound finishes.

I have replicated the issue using the play_sound example project and changing the button 1 action to look like:

    if (Common_BtnPress(BTN_ACTION1))
    {
        
        result = system->playSound(sound1, 0, false, &channel);
        channel->setCallback((FMOD_CHANNELCONTROL_CALLBACK)&ChannelControlCallback);
        ERRCHECK(result);
    }    

and then adding the callback

    static FMOD_RESULT F_CALLBACK ChannelControlCallback(FMOD_CHANNEL *channel,
                                                                FMOD_CHANNELCONTROL_CALLBACK_TYPE type,
                                                                unsigned int commanddata1,
                                                                unsigned int commanddata2) {
        if (type == FMOD_CHANNELCONTROL_CALLBACK_END) {
            printf("ChannelControlCallback: Sound finished\n");
        }
	    return FMOD_OK;
    }

When playing test-sound.wav I see “ChannelControlCallback: Sound finished” twice. When playing drumloop.wav I only see it once (when the sound actually finishes).

You have the wrong signature for your callback, you’re missing the second argument. The correct code would look like:

static FMOD_RESULT F_CALLBACK ChannelControlCallback(FMOD_CHANNELCONTROL *channelcontrol, FMOD_CHANNELCONTROL_TYPE controltype, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbacktype, void *commanddata1, void *commanddata2)

The FMOD_CHANNELCONTROL_TYPE argument is new in FMOD 5, and represents if the callback is happening on a Channel or a ChannelGroup.

You wav file has a tempo marker syncpoint at the start. FMOD is trying to send the syncpoint hit callback. You callback is mixing the arguments around and interpreting it as a channel end callback.