예제 #1
0
 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);
                 }
             }
         }
     }
 }
예제 #2
0
        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);
                        }
                    }
                }
            }
        }