public void Send(byte [] mevent, int offset, int length, long timestamp) { foreach (var evt in MidiEvent.Convert(mevent, offset, length)) { if (evt.StatusByte < 0xF0) { WinMMNatives.midiOutShortMsg(handle, (uint)(evt.StatusByte + (evt.Msb << 8) + (evt.Lsb << 16))); } else { MidiHdr sysex = default(MidiHdr); unsafe { fixed(void *ptr = evt.Data) { sysex.Data = (IntPtr)ptr; sysex.BufferLength = evt.Data.Length; sysex.Flags = 0; WinMMNatives.midiOutPrepareHeader(handle, ref sysex, (uint)Marshal.SizeOf(typeof(MidiHdr))); WinMMNatives.midiOutLongMsg(handle, ref sysex, evt.Data.Length); } } } } }
public void Send(byte [] mevent, int offset, int length, long timestamp) { foreach (var evt in MidiEvent.Convert(mevent, offset, length)) { if (evt.StatusByte < 0xF0) { DieOnError(WinMMNatives.midiOutShortMsg(handle, (uint)(evt.StatusByte + (evt.Msb << 8) + (evt.Lsb << 16)))); } else { var header = new MidiHdr(); bool prepared = false; IntPtr ptr = IntPtr.Zero; var hdrSize = Marshal.SizeOf(typeof(MidiHdr)); try { // allocate unmanaged memory and hand ownership over to the device driver header.Data = Marshal.AllocHGlobal(evt.Data.Length); header.BufferLength = evt.Data.Length; Marshal.Copy(evt.Data, 0, header.Data, header.BufferLength); ptr = Marshal.AllocHGlobal(hdrSize); Marshal.StructureToPtr(header, ptr, false); DieOnError(WinMMNatives.midiOutPrepareHeader(handle, ptr, hdrSize)); prepared = true; DieOnError(WinMMNatives.midiOutLongMsg(handle, ptr, hdrSize)); } finally { // reclaim ownership and free if (prepared) { DieOnError(WinMMNatives.midiOutUnprepareHeader(handle, ptr, hdrSize)); } if (header.Data != IntPtr.Zero) { Marshal.FreeHGlobal(header.Data); } if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } } } } }