示例#1
0
    /// This funcition dispatches all the accumulated callbacks from the native sound engine.
    /// It must be called regularly.  By default this is called in AkInitializer.cs.
    static public int PostCallbacks()
    {
        int numCallbacks = 0;

        if (m_pNotifMem == IntPtr.Zero)
        {
            return(numCallbacks);
        }

        IntPtr pData = AkCallbackSerializer.Lock();

        if (pData == IntPtr.Zero)
        {
            AkCallbackSerializer.Unlock();
            return(numCallbacks);
        }

        AkCommonCallback commonCB;

        commonCB.eType    = 0;
        commonCB.pPackage = IntPtr.Zero;
        commonCB.pNext    = IntPtr.Zero;

        IntPtr callbacksStart = pData;

        commonCB = new AkCommonCallback();

        commonCB.pPackage = Marshal.ReadIntPtr(pData);
        GotoEndOfCurrentStructMember_IntPtr(ref pData);

        commonCB.pNext = Marshal.ReadIntPtr(pData);
        GotoEndOfCurrentStructMember_IntPtr(ref pData);

        commonCB.eType = (AkCallbackType)Marshal.ReadInt32(pData);
        GotoEndOfCurrentStructMember_EnumType <AkCallbackType>(ref pData);

        EventCallbackPackage eventPkg = null;
        BankCallbackPackage  bankPkg  = null;

        if (!SafeExtractCallbackPackages(commonCB, out eventPkg, out bankPkg))
        {
            AkCallbackSerializer.Unlock();
            return(numCallbacks);
        }

        pData = callbacksStart;

        do
        {
            // Point to start of the next callback after commonCallback.
            pData = (IntPtr)(pData.ToInt64() + Marshal.SizeOf(typeof(AkCommonCallback)));

            if (commonCB.eType == AkCallbackType.AK_Monitoring)
            {
                AkMonitoringMsg monitorMsg = new AkMonitoringMsg();

                monitorMsg.errorCode = (ErrorCode)Marshal.ReadInt32(pData);
                // WG-25449
                GotoEndOfCurrentStructMember_ValueType <int>(ref pData);

                monitorMsg.errorLevel = (ErrorLevel)Marshal.ReadInt32(pData);
                // WG-25449
                GotoEndOfCurrentStructMember_ValueType <int>(ref pData);

                monitorMsg.playingID = (uint)Marshal.ReadInt32(pData);
                GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                monitorMsg.gameObjID = (IntPtr)Marshal.ReadIntPtr(pData);
                GotoEndOfCurrentStructMember_IntPtr(ref pData);

                // C# implementation of the struct does not include the tail string member, so as we skip sizes, pData is now at the actual start of the string member.
                monitorMsg.msg = SafeMarshalString(pData);
                if (m_MonitoringCB != null)
                {
                    m_MonitoringCB(monitorMsg.errorCode, monitorMsg.errorLevel, monitorMsg.playingID, monitorMsg.gameObjID, monitorMsg.msg);
                }
            }
            else if (commonCB.eType == AkCallbackType.AK_Bank)
            {
                AkBankInfo bankCB = new AkBankInfo();

                bankCB.bankID = (uint)Marshal.ReadInt32(pData);
                GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                bankCB.inMemoryBankPtr = Marshal.ReadIntPtr(pData);
                GotoEndOfCurrentStructMember_ValueType <IntPtr>(ref pData);

                bankCB.eLoadResult = (AKRESULT)Marshal.ReadInt32(pData);
                GotoEndOfCurrentStructMember_EnumType <AKRESULT>(ref pData);

                bankCB.memPoolId = (uint)Marshal.ReadInt32(pData);
                GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                if (bankPkg != null && bankPkg.m_Callback != null)
                {
                    bankPkg.m_Callback(bankCB.bankID, bankCB.inMemoryBankPtr, bankCB.eLoadResult, bankCB.memPoolId, bankPkg.m_Cookie);
                }
            }
#if UNITY_IOS && !UNITY_EDITOR
            else if (commonCB.eType == AkCallbackType.AK_AudioInterruption)
            {
                AkAudioInterruptionInfo cbInfo = new AkAudioInterruptionInfo();

                cbInfo.bEnterInterruption = Marshal.ReadInt32(pData);
                GotoEndOfCurrentStructMember_ValueType <Int32>(ref pData);

                if (ms_interruptCallbackPkg != null && ms_interruptCallbackPkg.m_Callback != null)
                {
                    ms_interruptCallbackPkg.m_Callback(cbInfo.bEnterInterruption, ms_interruptCallbackPkg.m_Cookie);
                }
            }
#endif // #if UNITY_IOS && ! UNITY_EDITOR
            else if (commonCB.eType == AkCallbackType.AK_AudioSourceChange)
            {
                AkBGMInfo cbInfo = new AkBGMInfo();

                cbInfo.bOtherAudioPlaying = Marshal.ReadInt32(pData);
                GotoEndOfCurrentStructMember_ValueType <Int32>(ref pData);

                if (ms_sourceChangeCallbackPkg != null && ms_sourceChangeCallbackPkg.m_Callback != null)
                {
                    ms_sourceChangeCallbackPkg.m_Callback(cbInfo.bOtherAudioPlaying, ms_sourceChangeCallbackPkg.m_Cookie);
                }
            }
            else
            {
                //Get the other parameters
                switch (commonCB.eType)
                {
                case AkCallbackType.AK_EndOfEvent:
                    AkEventCallbackInfo eventCB = new AkEventCallbackInfo();

                    eventCB.pCookie = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    eventCB.gameObjID = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    eventCB.playingID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    eventCB.eventID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    if (eventPkg.m_bNotifyEndOfEvent)
                    {
                        eventPkg.m_Callback(eventPkg.m_Cookie, commonCB.eType, eventCB);
                    }
                    m_mapEventCallbacks.Remove(eventPkg.GetHashCode());
                    break;

                case AkCallbackType.AK_EndOfDynamicSequenceItem:
                    AkDynamicSequenceItemCallbackInfo dynSeqInfoCB = new AkDynamicSequenceItemCallbackInfo();

                    dynSeqInfoCB.pCookie = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    dynSeqInfoCB.playingID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    dynSeqInfoCB.audioNodeID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    dynSeqInfoCB.pCustomInfo = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    eventPkg.m_Callback(eventPkg.m_Cookie, commonCB.eType, dynSeqInfoCB);
                    break;

                case AkCallbackType.AK_MIDIEvent:
                    AkMidiEventCallbackInfo midiEventInfo = new AkMidiEventCallbackInfo();

                    midiEventInfo.pCookie = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    midiEventInfo.gameObjID = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    midiEventInfo.playingID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    midiEventInfo.eventID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    midiEventInfo.byType = (byte)Marshal.ReadByte(pData);
                    GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);

                    midiEventInfo.byChan = (byte)Marshal.ReadByte(pData);
                    GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);

                    switch (midiEventInfo.byType)
                    {
                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_NOTE_OFF:                                     //Deliberate fall-through
                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_NOTE_ON:
                        midiEventInfo.byOnOffNote = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        midiEventInfo.byVelocity = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        break;

                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_NOTE_AFTERTOUCH:
                        midiEventInfo.byAftertouchNote = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        midiEventInfo.byNoteAftertouchValue = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        break;

                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_CONTROLLER:
                        // tCc
                        midiEventInfo.byCc = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        midiEventInfo.byCcValue = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        break;

                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_PROGRAM_CHANGE:
                        midiEventInfo.byProgramNum = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);                                        // skip unused 2nd member
                        break;

                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_CHANNEL_AFTERTOUCH:
                        midiEventInfo.byChanAftertouchValue = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);                                        // skip unused 2nd member
                        break;

                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_PITCH_BEND:
                        midiEventInfo.byValueLsb = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        midiEventInfo.byValueMsb = (byte)Marshal.ReadByte(pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        break;

                    // mcooper quote: "You won't get these"
                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_SYSEX:
                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_ESCAPE:
                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_META:
                    case AkSoundEngine.AK_MIDI_EVENT_TYPE_INVALID:
                    default:
                        // Do nothing except skip the next two members
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        GotoEndOfCurrentStructMember_ValueType <byte>(ref pData);
                        break;
                    }

                    eventPkg.m_Callback(eventPkg.m_Cookie, commonCB.eType, midiEventInfo);
                    break;

                case AkCallbackType.AK_Marker:
                    AkMarkerCallbackInfo markerInfo = new AkMarkerCallbackInfo();

                    markerInfo.pCookie = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    markerInfo.gameObjID = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    markerInfo.playingID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    markerInfo.eventID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    markerInfo.uIdentifier = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    markerInfo.uPosition = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    markerInfo.strLabel = SafeMarshalMarkerString(pData);

                    eventPkg.m_Callback(eventPkg.m_Cookie, commonCB.eType, markerInfo);
                    break;

                case AkCallbackType.AK_Duration:
                    AkDurationCallbackInfo durInfoCB = new AkDurationCallbackInfo();

                    durInfoCB.pCookie = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    durInfoCB.gameObjID = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    durInfoCB.playingID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    durInfoCB.eventID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    durInfoCB.fDuration = MarshalFloat32(pData);
                    GotoEndOfCurrentStructMember_ValueType <float>(ref pData);

                    durInfoCB.fEstimatedDuration = MarshalFloat32(pData);
                    GotoEndOfCurrentStructMember_ValueType <float>(ref pData);

                    durInfoCB.audioNodeID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    durInfoCB.mediaID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    durInfoCB.bStreaming = Convert.ToBoolean(Marshal.ReadInt32(pData));
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    eventPkg.m_Callback(eventPkg.m_Cookie, commonCB.eType, durInfoCB);
                    break;

                case AkCallbackType.AK_MusicSyncUserCue:
                case AkCallbackType.AK_MusicPlayStarted:
                case AkCallbackType.AK_MusicSyncBar:
                case AkCallbackType.AK_MusicSyncBeat:
                case AkCallbackType.AK_MusicSyncEntry:
                case AkCallbackType.AK_MusicSyncExit:
                case AkCallbackType.AK_MusicSyncGrid:
                case AkCallbackType.AK_MusicSyncPoint:
                    AkMusicSyncCallbackInfo pInfo = new AkMusicSyncCallbackInfo();

                    pInfo.pCookie = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    pInfo.gameObjID = Marshal.ReadIntPtr(pData);
                    GotoEndOfCurrentStructMember_IntPtr(ref pData);

                    pInfo.playingID = (uint)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <uint>(ref pData);

                    pInfo.segmentInfo.iCurrentPosition = Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <int>(ref pData);

                    pInfo.segmentInfo.iPreEntryDuration = Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <int>(ref pData);

                    pInfo.segmentInfo.iActiveDuration = Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <int>(ref pData);

                    pInfo.segmentInfo.iPostExitDuration = Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <int>(ref pData);

                    pInfo.segmentInfo.iRemainingLookAheadTime = Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_ValueType <int>(ref pData);

                    pInfo.segmentInfo.fBeatDuration = MarshalFloat32(pData);
                    GotoEndOfCurrentStructMember_ValueType <float>(ref pData);

                    pInfo.segmentInfo.fBarDuration = MarshalFloat32(pData);
                    GotoEndOfCurrentStructMember_ValueType <float>(ref pData);

                    pInfo.segmentInfo.fGridDuration = MarshalFloat32(pData);
                    GotoEndOfCurrentStructMember_ValueType <float>(ref pData);

                    pInfo.segmentInfo.fGridOffset = MarshalFloat32(pData);
                    GotoEndOfCurrentStructMember_ValueType <float>(ref pData);

                    pInfo.musicSyncType = (AkCallbackType)Marshal.ReadInt32(pData);
                    GotoEndOfCurrentStructMember_EnumType <AkCallbackType>(ref pData);

                    // WG-22334: User cues are always ANSI char*.
                    pInfo.pszUserCueName = Marshal.PtrToStringAnsi(pData);

                    eventPkg.m_Callback(eventPkg.m_Cookie, commonCB.eType, pInfo);
                    break;

                default:
                    string log = string.Format("WwiseUnity: PostCallbacks aborted due to error: Undefined callback type found. Callback object possibly corrupted.");
                    Debug.LogError(log);
                    AkCallbackSerializer.Unlock();
                    return(numCallbacks);
                }
                ;
            }

            numCallbacks++;
            if (commonCB.pNext == IntPtr.Zero)
            {
                break;
            }

            // Note: At the end of each callback case above, pData points to either end of the callback struct, or right before the tail string member of the struct.
            pData = commonCB.pNext;

            callbacksStart = pData;

            commonCB = new AkCommonCallback();

            commonCB.pPackage = (IntPtr)Marshal.ReadIntPtr(pData);
            GotoEndOfCurrentStructMember_IntPtr(ref pData);

            commonCB.pNext = (IntPtr)Marshal.ReadIntPtr(pData);
            GotoEndOfCurrentStructMember_IntPtr(ref pData);

            commonCB.eType = (AkCallbackType)Marshal.ReadInt32(pData);
            GotoEndOfCurrentStructMember_EnumType <AkCallbackType>(ref pData);

            eventPkg = null;
            bankPkg  = null;

            if (!SafeExtractCallbackPackages(commonCB, out eventPkg, out bankPkg))
            {
                AkCallbackSerializer.Unlock();
                return(numCallbacks);
            }

            pData = callbacksStart;
        } while (true);

        AkCallbackSerializer.Unlock();
        return(numCallbacks);
    }
示例#2
0
    /// This function dispatches all the accumulated callbacks from the native sound engine.
    /// It must be called regularly.  By default this is called in AkInitializer.cs.
    static public int PostCallbacks()
    {
        if (m_pNotifMem == IntPtr.Zero)
        {
            return(0);
        }

        try
        {
            int numCallbacks = 0;

            for (IntPtr pNext = AkCallbackSerializer.Lock(); pNext != IntPtr.Zero; pNext = AkSoundEnginePINVOKE.CSharp_AkSerializedCallbackHeader_pNext_get(pNext), ++numCallbacks)
            {
                IntPtr         pPackage = AkSoundEnginePINVOKE.CSharp_AkSerializedCallbackHeader_pPackage_get(pNext);
                AkCallbackType eType    = (AkCallbackType)AkSoundEnginePINVOKE.CSharp_AkSerializedCallbackHeader_eType_get(pNext);
                IntPtr         pData    = AkSoundEnginePINVOKE.CSharp_AkSerializedCallbackHeader_GetData(pNext);

                switch (eType)
                {
                case AkCallbackType.AK_AudioInterruption:
#if UNITY_IOS && !UNITY_EDITOR
                    if (ms_interruptCallbackPkg != null && ms_interruptCallbackPkg.m_Callback != null)
                    {
                        AkAudioInterruptionCallbackInfo.setCPtr(pData);
                        ms_interruptCallbackPkg.m_Callback(AkAudioInterruptionCallbackInfo.bEnterInterruption, ms_interruptCallbackPkg.m_Cookie);
                    }
#endif // #if UNITY_IOS && ! UNITY_EDITOR
                    break;

                case AkCallbackType.AK_AudioSourceChange:
                    if (ms_sourceChangeCallbackPkg != null && ms_sourceChangeCallbackPkg.m_Callback != null)
                    {
                        AkAudioSourceChangeCallbackInfo.setCPtr(pData);
                        ms_sourceChangeCallbackPkg.m_Callback(AkAudioSourceChangeCallbackInfo.bOtherAudioPlaying, ms_sourceChangeCallbackPkg.m_Cookie);
                    }
                    break;

                case AkCallbackType.AK_Monitoring:
                    if (m_MonitoringCB != null)
                    {
                        AkMonitoringCallbackInfo.setCPtr(pData);
                        m_MonitoringCB(AkMonitoringCallbackInfo.errorCode, AkMonitoringCallbackInfo.errorLevel, AkMonitoringCallbackInfo.playingID,
                                       AkMonitoringCallbackInfo.gameObjID, AkMonitoringCallbackInfo.message);
                    }
#if UNITY_EDITOR
                    else if (AkSoundEngineController.Instance.engineLogging)
                    {
                        AkMonitoringCallbackInfo.setCPtr(pData);

                        string msg = "Wwise: " + AkMonitoringCallbackInfo.message;
                        if (AkMonitoringCallbackInfo.gameObjID != AkSoundEngine.AK_INVALID_GAME_OBJECT)
                        {
                            var obj = EditorUtility.InstanceIDToObject((int)AkMonitoringCallbackInfo.gameObjID) as GameObject;
                            if (obj != null)
                            {
                                msg += " (GameObject: " + obj.ToString() + ")";
                            }

                            msg += " (Instance ID: " + AkMonitoringCallbackInfo.gameObjID.ToString() + ")";
                        }

                        if (AkMonitoringCallbackInfo.errorLevel == AkMonitorErrorLevel.ErrorLevel_Error)
                        {
                            Debug.LogError(msg);
                        }
                        else
                        {
                            Debug.Log(msg);
                        }
                    }
#endif
                    break;

                case AkCallbackType.AK_Bank:
                    BankCallbackPackage bankPkg = null;
                    if (!m_mapBankCallbacks.TryGetValue((int)pPackage, out bankPkg))
                    {
                        Debug.LogError("WwiseUnity: BankCallbackPackage not found for <" + pPackage + ">.");
                        return(numCallbacks);
                    }
                    else
                    {
                        m_mapBankCallbacks.Remove((int)pPackage);

                        if (bankPkg != null && bankPkg.m_Callback != null)
                        {
                            AkBankCallbackInfo.setCPtr(pData);
                            bankPkg.m_Callback(AkBankCallbackInfo.bankID, AkBankCallbackInfo.inMemoryBankPtr, AkBankCallbackInfo.loadResult,
                                               (uint)AkBankCallbackInfo.memPoolId, bankPkg.m_Cookie);
                        }
                    }
                    break;

                default:
                    EventCallbackPackage eventPkg = null;
                    if (!m_mapEventCallbacks.TryGetValue((int)pPackage, out eventPkg))
                    {
                        Debug.LogError("WwiseUnity: EventCallbackPackage not found for <" + pPackage + ">.");
                        return(numCallbacks);
                    }
                    else
                    {
                        AkCallbackInfo info = null;

                        switch (eType)
                        {
                        case AkCallbackType.AK_EndOfEvent:
                            m_mapEventCallbacks.Remove(eventPkg.GetHashCode());
                            if (eventPkg.m_bNotifyEndOfEvent)
                            {
                                AkEventCallbackInfo.setCPtr(pData);
                                info = AkEventCallbackInfo;
                            }
                            break;

                        case AkCallbackType.AK_MusicPlayStarted:
                            AkEventCallbackInfo.setCPtr(pData);
                            info = AkEventCallbackInfo;
                            break;

                        case AkCallbackType.AK_EndOfDynamicSequenceItem:
                            AkDynamicSequenceItemCallbackInfo.setCPtr(pData);
                            info = AkDynamicSequenceItemCallbackInfo;
                            break;

                        case AkCallbackType.AK_MIDIEvent:
                            AkMIDIEventCallbackInfo.setCPtr(pData);
                            info = AkMIDIEventCallbackInfo;
                            break;

                        case AkCallbackType.AK_Marker:
                            AkMarkerCallbackInfo.setCPtr(pData);
                            info = AkMarkerCallbackInfo;
                            break;

                        case AkCallbackType.AK_Duration:
                            AkDurationCallbackInfo.setCPtr(pData);
                            info = AkDurationCallbackInfo;
                            break;

                        case AkCallbackType.AK_MusicSyncUserCue:
                        case AkCallbackType.AK_MusicSyncBar:
                        case AkCallbackType.AK_MusicSyncBeat:
                        case AkCallbackType.AK_MusicSyncEntry:
                        case AkCallbackType.AK_MusicSyncExit:
                        case AkCallbackType.AK_MusicSyncGrid:
                        case AkCallbackType.AK_MusicSyncPoint:
                            AkMusicSyncCallbackInfo.setCPtr(pData);
                            info = AkMusicSyncCallbackInfo;
                            break;

                        case AkCallbackType.AK_MusicPlaylistSelect:
                            AkMusicPlaylistCallbackInfo.setCPtr(pData);
                            info = AkMusicPlaylistCallbackInfo;
                            break;

                        default:
                            Debug.LogError("WwiseUnity: PostCallbacks aborted due to error: Undefined callback type <" + eType + "> found. Callback object possibly corrupted.");
                            return(numCallbacks);
                        }

                        if (info != null)
                        {
                            eventPkg.m_Callback(eventPkg.m_Cookie, eType, info);
                        }
                    }
                    break;
                }
            }

            return(numCallbacks);
        }
        finally
        {
            AkCallbackSerializer.Unlock();
        }
    }
    /// This function dispatches all the accumulated callbacks from the native sound engine.
    /// It must be called regularly.  By default this is called in AkInitializer.cs.
    static public int PostCallbacks()
    {
        if (m_pNotifMem == IntPtr.Zero)
        {
            return(0);
        }

        try
        {
            int numCallbacks = 0;

            for (IntPtr pNext = AkCallbackSerializer.Lock(); pNext != IntPtr.Zero; pNext = AkSoundEnginePINVOKE.CSharp_AkSerializedCallbackHeader_pNext_get(pNext), ++numCallbacks)
            {
                IntPtr         pPackage = AkSoundEnginePINVOKE.CSharp_AkSerializedCallbackHeader_pPackage_get(pNext);
                AkCallbackType eType    = (AkCallbackType)AkSoundEnginePINVOKE.CSharp_AkSerializedCallbackHeader_eType_get(pNext);
                IntPtr         pData    = AkSoundEnginePINVOKE.CSharp_AkSerializedCallbackHeader_GetData(pNext);

                switch (eType)
                {
                case AkCallbackType.AK_AudioInterruption:
#if UNITY_IOS && !UNITY_EDITOR
                    if (ms_interruptCallbackPkg != null && ms_interruptCallbackPkg.m_Callback != null)
                    {
                        using (AkAudioInterruptionCallbackInfo info = new AkAudioInterruptionCallbackInfo(pData, false))
                            ms_interruptCallbackPkg.m_Callback(info.bEnterInterruption, ms_interruptCallbackPkg.m_Cookie);
                    }
#endif // #if UNITY_IOS && ! UNITY_EDITOR
                    break;

                case AkCallbackType.AK_AudioSourceChange:
                    if (ms_sourceChangeCallbackPkg != null && ms_sourceChangeCallbackPkg.m_Callback != null)
                    {
                        using (AkAudioSourceChangeCallbackInfo info = new AkAudioSourceChangeCallbackInfo(pData, false))
                            ms_sourceChangeCallbackPkg.m_Callback(info.bOtherAudioPlaying, ms_sourceChangeCallbackPkg.m_Cookie);
                    }
                    break;

                case AkCallbackType.AK_Monitoring:
                    if (m_MonitoringCB != null)
                    {
                        using (AkMonitoringCallbackInfo info = new AkMonitoringCallbackInfo(pData, false))
                            m_MonitoringCB(info.errorCode, info.errorLevel, info.playingID, info.gameObjID, info.message);
                    }
                    break;

                case AkCallbackType.AK_Bank:
                    BankCallbackPackage bankPkg = null;
                    if (!m_mapBankCallbacks.TryGetValue((int)pPackage, out bankPkg))
                    {
                        Debug.LogError("WwiseUnity: BankCallbackPackage not found for <" + pPackage + ">.");
                        return(numCallbacks);
                    }
                    else
                    {
                        m_mapBankCallbacks.Remove((int)pPackage);

                        if (bankPkg != null && bankPkg.m_Callback != null)
                        {
                            using (AkBankCallbackInfo info = new AkBankCallbackInfo(pData, false))
                                bankPkg.m_Callback(info.bankID, info.inMemoryBankPtr, info.loadResult, (uint)info.memPoolId, bankPkg.m_Cookie);
                        }
                    }
                    break;

                default:
                    EventCallbackPackage eventPkg = null;
                    if (!m_mapEventCallbacks.TryGetValue((int)pPackage, out eventPkg))
                    {
                        Debug.LogError("WwiseUnity: EventCallbackPackage not found for <" + pPackage + ">.");
                        return(numCallbacks);
                    }
                    else
                    {
                        AkCallbackInfo info = null;

                        switch (eType)
                        {
                        case AkCallbackType.AK_EndOfEvent:
                            m_mapEventCallbacks.Remove(eventPkg.GetHashCode());
                            if (eventPkg.m_bNotifyEndOfEvent)
                            {
                                info = new AkEventCallbackInfo(pData, false);
                            }
                            break;

                        case AkCallbackType.AK_MusicPlayStarted:
                            info = new AkEventCallbackInfo(pData, false);
                            break;

                        case AkCallbackType.AK_EndOfDynamicSequenceItem:
                            info = new AkDynamicSequenceItemCallbackInfo(pData, false);
                            break;

                        case AkCallbackType.AK_MIDIEvent:
                            info = new AkMIDIEventCallbackInfo(pData, false);
                            break;

                        case AkCallbackType.AK_Marker:
                            info = new AkMarkerCallbackInfo(pData, false);
                            break;

                        case AkCallbackType.AK_Duration:
                            info = new AkDurationCallbackInfo(pData, false);
                            break;

                        case AkCallbackType.AK_MusicSyncUserCue:
                        case AkCallbackType.AK_MusicSyncBar:
                        case AkCallbackType.AK_MusicSyncBeat:
                        case AkCallbackType.AK_MusicSyncEntry:
                        case AkCallbackType.AK_MusicSyncExit:
                        case AkCallbackType.AK_MusicSyncGrid:
                        case AkCallbackType.AK_MusicSyncPoint:
                            info = new AkMusicSyncCallbackInfo(pData, false);
                            break;

                        case AkCallbackType.AK_MusicPlaylistSelect:
                            info = new AkMusicPlaylistCallbackInfo(pData, false);
                            break;

                        default:
                            Debug.LogError("WwiseUnity: PostCallbacks aborted due to error: Undefined callback type <" + eType + "> found. Callback object possibly corrupted.");
                            return(numCallbacks);
                        }

                        if (info != null)
                        {
                            eventPkg.m_Callback(eventPkg.m_Cookie, eType, info);
                        }
                    }
                    break;
                }
            }

            return(numCallbacks);
        }
        finally
        {
            AkCallbackSerializer.Unlock();
        }
    }