/// <summary>
        /// Sends a System Exclusive (sysex) message.
        /// </summary>
        /// <param name="data">The message to send (as byte array)</param>
        /// <exception cref="DeviceException">The message cannot be sent.</exception>
        public void SendSysEx(byte[] data)
        {
            lock (_lockObj)
            {
                //Win32API.MMRESULT result;
                IntPtr           ptr;
                UInt32           size   = (UInt32)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32API.MIDIHDR));
                Win32API.MIDIHDR header = new Win32API.MIDIHDR();
                header.lpData = System.Runtime.InteropServices.Marshal.AllocHGlobal(data.Length);
                for (int i = 0; i < data.Length; i++)
                {
                    System.Runtime.InteropServices.Marshal.WriteByte(header.lpData, i, data[i]);
                }
                header.dwBufferLength  = data.Length;
                header.dwBytesRecorded = data.Length;
                header.dwFlags         = 0;

                try
                {
                    ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32API.MIDIHDR)));
                }
                catch (Exception)
                {
                    System.Runtime.InteropServices.Marshal.FreeHGlobal(header.lpData);
                    throw;
                }

                try
                {
                    System.Runtime.InteropServices.Marshal.StructureToPtr(header, ptr, false);
                }
                catch (Exception)
                {
                    System.Runtime.InteropServices.Marshal.FreeHGlobal(header.lpData);
                    System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
                    throw;
                }

                //result = Win32API.midiOutPrepareHeader(handle, ptr, size);
                //if (result == 0) result = Win32API.midiOutLongMsg(handle, ptr, size);
                //if (result == 0) result = Win32API.midiOutUnprepareHeader(handle, ptr, size);
                CheckReturnCode(Win32API.midiOutPrepareHeader(_handle, ptr, size));
                CheckReturnCode(Win32API.midiOutLongMsg(_handle, ptr, size));
                CheckReturnCode(Win32API.midiOutUnprepareHeader(_handle, ptr, size));

                System.Runtime.InteropServices.Marshal.FreeHGlobal(header.lpData);
                System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
            }
        }
        /// <summary>
        /// Releases the resources associated with the specified MidiHeader pointer.
        /// </summary>
        /// <param name="ptr">
        /// The pointer to MIDIHDR buffer.
        /// </param>
        private bool DestroyLongMsgBuffer(UIntPtr ptr)
        {
            IntPtr newPtr = unchecked ((IntPtr)(long)(ulong)ptr);
            uint   size   = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32API.MIDIHDR));

            CheckReturnCode(Win32API.midiInUnprepareHeader(_handle, newPtr, size));

            Win32API.MIDIHDR header = (Win32API.MIDIHDR)System.Runtime.InteropServices.Marshal.PtrToStructure(newPtr, typeof(Win32API.MIDIHDR));
            System.Runtime.InteropServices.Marshal.FreeHGlobal(header.lpData);
            System.Runtime.InteropServices.Marshal.FreeHGlobal(newPtr);

            _longMsgBuffers.Remove(newPtr);

            return(true);
        }
        private IntPtr CreateLongMsgBuffer()
        {
            //add a buffer so we can receive SysEx messages
            IntPtr ptr;
            uint   size = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32API.MIDIHDR));

            Win32API.MIDIHDR header = new Win32API.MIDIHDR
            {
                lpData         = System.Runtime.InteropServices.Marshal.AllocHGlobal(4096),
                dwBufferLength = 4096,
                dwFlags        = 0
            };

            try
            {
                ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32API.MIDIHDR)));
            }
            catch (Exception)
            {
                System.Runtime.InteropServices.Marshal.FreeHGlobal(header.lpData);
                throw;
            }

            try
            {
                System.Runtime.InteropServices.Marshal.StructureToPtr(header, ptr, false);
            }
            catch (Exception)
            {
                System.Runtime.InteropServices.Marshal.FreeHGlobal(header.lpData);
                System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
                throw;
            }

            CheckReturnCode(Win32API.midiInPrepareHeader(_handle, ptr, size));
            CheckReturnCode(Win32API.midiInAddBuffer(_handle, ptr, size));
            //CheckReturnCode(Win32API.midiInUnprepareHeader(handle, ptr, size));

            return(ptr);
        }