Example #1
0
        public IXAudio2VoiceCallbackWrapper(IXAudio2VoiceCallback callback)
        {
            if (callback == null)
            {
                return;
            }

            _callback = callback;
            // Store callbacks to prevent them from being garbage collected
            _startCallback       = (_, bytesRequired) => _callback.OnVoiceProcessingPassStart(bytesRequired);
            _endCallback         = _ => _callback.OnVoiceProcessingPassEnd();
            _streamEndCallback   = _ => _callback.OnStreamEnd();
            _bufferStartCallback = (_, context) => _callback.OnBufferStart(context);
            _bufferEndCallback   = (_, context) => _callback.OnBufferEnd(context);
            _loopEndCallback     = (_, context) => _callback.OnLoopEnd(context);
            _voiceErrorCallback  = (_, context, error) => _callback.OnVoiceError(context, error);

            // Allocate memory for the C++ interface
            _nativePointer = Marshal.AllocHGlobal(IntPtr.Size * 8); // 7 methods + vtbl

            // Write pointer to vtbl
            Marshal.WriteIntPtr(_nativePointer, IntPtr.Add(_nativePointer, IntPtr.Size));

            // Write the functions to the vtable
            WriteFunctionPointer(1, _startCallback);
            WriteFunctionPointer(2, _endCallback);
            WriteFunctionPointer(3, _streamEndCallback);
            WriteFunctionPointer(4, _bufferStartCallback);
            WriteFunctionPointer(5, _bufferEndCallback);
            WriteFunctionPointer(6, _loopEndCallback);
            WriteFunctionPointer(7, _voiceErrorCallback);
        }