Ejemplo n.º 1
0
        void _SendRaw(byte[] data, int startIndex, int length)
        {
            var hdrSize = Marshal.SizeOf(typeof(MIDIHDR));
            var hdr     = new MIDIHDR();
            var handle  = GCHandle.Alloc(data, GCHandleType.Pinned);

            try
            {
                hdr.lpData         = new IntPtr(handle.AddrOfPinnedObject().ToInt64() + startIndex);
                hdr.dwBufferLength = hdr.dwBytesRecorded = (uint)(length);
                hdr.dwFlags        = 0;
                _CheckOutResult(midiOutPrepareHeader(_handle, ref hdr, hdrSize));
                while ((hdr.dwFlags & MHDR_PREPARED) != MHDR_PREPARED)
                {
                    Thread.Sleep(1);
                }
                _CheckOutResult(midiOutLongMsg(_handle, ref hdr, hdrSize));
                while ((hdr.dwFlags & MHDR_DONE) != MHDR_DONE)
                {
                    Thread.Sleep(1);
                }
                _CheckOutResult(midiOutUnprepareHeader(_handle, ref hdr, hdrSize));
            }
            finally
            {
                handle.Free();
            }
        }
Ejemplo n.º 2
0
        public void SendSysEx(byte[] data)
        {
            lock (this)
            {
                //Win32API.MMRESULT result;
                IntPtr ptr;
                var    size   = (uint)Marshal.SizeOf(typeof(MIDIHDR));
                var    header = new MIDIHDR {
                    lpData = Marshal.AllocHGlobal(data.Length)
                };
                for (var i = 0; i < data.Length; i++)
                {
                    Marshal.WriteByte(header.lpData, i, data[i]);
                }
                header.dwBufferLength  = data.Length;
                header.dwBytesRecorded = data.Length;
                header.dwFlags         = 0;

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

                try
                {
                    Marshal.StructureToPtr(header, ptr, false);
                }
                catch (Exception)
                {
                    Marshal.FreeHGlobal(header.lpData);
                    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));

                Marshal.FreeHGlobal(header.lpData);
                Marshal.FreeHGlobal(ptr);
            }
        }
Ejemplo n.º 3
0
 internal MidiStream(int deviceIndex)
 {
     if (0 > deviceIndex)
     {
         throw new ArgumentOutOfRangeException("deviceIndex");
     }
     _deviceIndex                = deviceIndex;
     _handle                     = IntPtr.Zero;
     _sendHeader                 = default(MIDIHDR);
     _sendEventBuffer            = IntPtr.Zero;
     _sendQueuePosition          = 0;
     _outCallback                = new MidiOutProc(_MidiOutProc);
     _timerCallback              = new TimerProc(_TimerProc);
     _tempoSyncEnabled           = 0;
     _tempoSyncMessageCount      = 100;
     _tempoSyncMessagesSentCount = 0;
 }
Ejemplo n.º 4
0
        /*private void SendLong_old( byte[] data ) {
         *  MIDIHDR hdr = new MIDIHDR();
         *  GCHandle dataHandle = GCHandle.Alloc( data, GCHandleType.Pinned ); // monoでコンパイルできない
         *  uint size = (uint)sizeof( MIDIHDR );
         *  try {
         *      hdr.lpData = (byte*)dataHandle.AddrOfPinnedObject().ToPointer();
         *      hdr.dwBufferLength = (uint)data.Length;
         *      hdr.dwFlags = 0;
         *      win32.midiOutPrepareHeader( m_handle, ref hdr, size );
         *      while ( (hdr.dwFlags & win32.WHDR_PREPARED) != win32.WHDR_PREPARED ) {
         *          Application.DoEvents();
         *      }
         *      win32.midiOutLongMsg( m_handle, ref hdr, size );
         *      while ( (hdr.dwFlags & win32.WHDR_DONE) != win32.WHDR_DONE ) {
         *          Application.DoEvents();
         *      }
         *      win32.midiOutUnprepareHeader( m_handle, ref hdr, size );
         *  } finally {
         *      dataHandle.Free();
         *  }
         * }*/
#endif

        private void SendLong(byte[] data)
        {
#if !MONO
            IntPtr ptr     = IntPtr.Zero;
            IntPtr ptrData = IntPtr.Zero;
            try {
                uint size = (uint)sizeof(MIDIHDR);
                ptr = Marshal.AllocHGlobal((int)size);
                MIDIHDR hdr = (MIDIHDR)Marshal.PtrToStructure(ptr, typeof(MIDIHDR));
                ptrData = Marshal.AllocHGlobal(data.Length);
                byte *pData = (byte *)ptrData.ToPointer();
                for (int i = 0; i < data.Length; i++)
                {
                    pData[i] = data[i];
                }
                hdr.lpData         = pData;
                hdr.dwBufferLength = (uint)data.Length;
                hdr.dwFlags        = 0;
                win32.midiOutPrepareHeader(m_handle, ref hdr, size);
                while ((hdr.dwFlags & win32.WHDR_PREPARED) != win32.WHDR_PREPARED)
                {
                    Application.DoEvents();
                }
                win32.midiOutLongMsg(m_handle, ref hdr, size);
                while ((hdr.dwFlags & win32.WHDR_DONE) != win32.WHDR_DONE)
                {
                    Application.DoEvents();
                }
                win32.midiOutUnprepareHeader(m_handle, ref hdr, size);
            } catch (Exception ex) {
                serr.println("MidiOutDevice#SendLong; ex=" + ex);
            } finally {
                if (ptrData != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ptrData);
                }
                if (ptr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
#endif
        }
            public MidiInputLongDataBuffer(HMIDIIN inputHandle, int bufferSize = 4096)
            {
                _inputHandle = inputHandle;

                var header = new MIDIHDR()
                {
                    lpData         = Marshal.AllocHGlobal(bufferSize),
                    dwBufferLength = (uint)bufferSize,
                };

                try
                {
                    Ptr = Marshal.AllocHGlobal(Marshal.SizeOf <MIDIHDR>());
                    Marshal.StructureToPtr(header, Ptr, false);
                }
                catch
                {
                    Free();
                    throw;
                }
            }
Ejemplo n.º 6
0
        private IntPtr CreateLongMsgBuffer()
        {
            //add a buffer so we can receive SysEx messages
            IntPtr ptr;
            var    size   = (uint)Marshal.SizeOf(typeof(MIDIHDR));
            var    header = new MIDIHDR
            {
                lpData         = Marshal.AllocHGlobal(4096),
                dwBufferLength = 4096,
                dwFlags        = 0
            };

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

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

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

            return(ptr);
        }
Ejemplo n.º 7
0
 public static extern MmResult midiStreamOut(IntPtr hMidiStream, [MarshalAs(UnmanagedType.Struct)] ref MIDIHDR pmh, int cbmh);
Ejemplo n.º 8
0
 public static extern MmResult midiOutLongMsg(IntPtr hMidiOut, [MarshalAs(UnmanagedType.Struct)] ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 9
0
 public static extern int midiStreamOut(int hms, ref MIDIHDR pmh, int cbmh);
Ejemplo n.º 10
0
 public static extern int midiOutLongMsg(int hMidiOUT, ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 11
0
 public static extern int midiInAddBuffer(int hMidiIN, ref MIDIHDR lpMidiInHdr, int uSize);
Ejemplo n.º 12
0
 static extern int midiInAddBuffer(IntPtr handle, ref MIDIHDR lpMidiHeader, int wSize);
Ejemplo n.º 13
0
 static extern int midiOutUnprepareHeader(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 14
0
 public static extern MmResult midiInPrepareHeader(IntPtr hMidiIn, ref MIDIHDR lpMidiInHdr, int uSize);
Ejemplo n.º 15
0
 public static extern int midiOutLongMsg(int hMidiOUT, ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 16
0
 public static extern uint UnprepareLongData(ref MIDIHDR IIMidiHdr);
Ejemplo n.º 17
0
 public static extern uint SendDirectLongDataNoBuf(ref MIDIHDR IIMidiHdr);
Ejemplo n.º 18
0
 internal static extern uint midiOutUnprepareHeader(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, uint uSize);
Ejemplo n.º 19
0
 internal static extern uint midiOutLongMsg(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, uint uSize);
Ejemplo n.º 20
0
 internal static extern uint midiOutPrepareHeader(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, uint uSize);
Ejemplo n.º 21
0
 public static extern int midiStreamOut(int hms, ref MIDIHDR pmh, int cbmh);
Ejemplo n.º 22
0
 public static extern int midiInUnprepareHeader(int hMidiIN, ref MIDIHDR lpMidiInHdr, int uSize);
Ejemplo n.º 23
0
 public static extern MmResult midiOutLongMsg(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 24
0
 static extern int midiOutLongMsg(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 25
0
 public static extern MmResult midiOutUnprepareHeader(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 26
0
 static extern int midiInUnprepareHeader(IntPtr handle, ref MIDIHDR lpMidiHeader, int wSize);
Ejemplo n.º 27
0
 public static extern MmResult midiStreamOut(IntPtr hMidiStream, ref MIDIHDR pmh, int cbmh);
Ejemplo n.º 28
0
 public static extern int midiInUnprepareHeader(int hMidiIN, ref MIDIHDR lpMidiInHdr, int uSize);
Ejemplo n.º 29
0
 public static extern MmResult midiInAddBuffer(IntPtr hMidiIn, ref MIDIHDR lpMidiInHdr, int uSize);
Ejemplo n.º 30
0
 public static extern int midiOutUnprepareHeader(int hMidiOUT, ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 31
0
        void _SendBlock()
        {
            if (null == _sendQueue)
            {
                return;
            }
            if (IntPtr.Zero == _handle)
            {
                throw new InvalidOperationException("The stream is closed.");
            }

            if (IntPtr.Zero != Interlocked.CompareExchange(ref _sendHeader.lpData, _sendEventBuffer, IntPtr.Zero))
            {
                throw new InvalidOperationException("The stream is busy playing.");
            }

            int    baseEventSize = Marshal.SizeOf(typeof(MIDIEVENT));
            int    blockSize     = 0;
            IntPtr eventPointer  = _sendEventBuffer;
            var    ofs           = 0;
            var    ptrOfs        = 0;

            for (; _sendQueuePosition < _sendQueue.Count; Interlocked.Exchange(ref _sendQueuePosition, _sendQueuePosition + 1))
            {
                var @event = _sendQueue[_sendQueuePosition];
                if (0x00 != @event.Message.Status && 0xF0 != (@event.Message.Status & 0xF0))
                {
                    if (_SendBufferSize < blockSize + baseEventSize)
                    {
                        break;
                    }
                    blockSize += baseEventSize;
                    var se = new MIDIEVENT();
                    se.dwDeltaTime = @event.Position + ofs;
                    se.dwStreamId  = 0;
                    se.dwEvent     = MidiUtility.PackMessage(@event.Message);
                    var gch = GCHandle.Alloc(se, GCHandleType.Pinned);
                    CopyMemory(new IntPtr(ptrOfs + eventPointer.ToInt64()), gch.AddrOfPinnedObject(), Marshal.SizeOf(typeof(MIDIEVENT)));
                    gch.Free();
                    ptrOfs += baseEventSize;
                    ofs     = 0;
                }
                else if (0xFF == @event.Message.Status)
                {
                    var mm = @event.Message as MidiMessageMeta;
                    if (0x51 == mm.Data1)                     // tempo
                    {
                        if (_SendBufferSize < blockSize + baseEventSize)
                        {
                            break;
                        }
                        blockSize += baseEventSize;
                        var se = new MIDIEVENT();
                        se.dwDeltaTime = @event.Position + ofs;
                        se.dwStreamId  = 0;
                        se.dwEvent     = (mm.Data[0] << 16) | (mm.Data[1] << 8) | mm.Data[2] | (MEVT_TEMPO << 24);
                        var gch = GCHandle.Alloc(se, GCHandleType.Pinned);
                        CopyMemory(new IntPtr(ptrOfs + eventPointer.ToInt64()), gch.AddrOfPinnedObject(), Marshal.SizeOf(typeof(MIDIEVENT)));
                        gch.Free();
                        ptrOfs += baseEventSize;
                        ofs     = 0;
                    }
                    else if (0x2f == mm.Data1)                     // end track
                    {
                        if (_SendBufferSize < blockSize + baseEventSize)
                        {
                            break;
                        }
                        blockSize += baseEventSize;

                        // add a NOP message to it just to pad our output in case we're looping
                        var se = new MIDIEVENT();
                        se.dwDeltaTime = @event.Position + ofs;
                        se.dwStreamId  = 0;
                        se.dwEvent     = (MEVT_NOP << 24);
                        var gch = GCHandle.Alloc(se, GCHandleType.Pinned);
                        CopyMemory(new IntPtr(ptrOfs + eventPointer.ToInt64()), gch.AddrOfPinnedObject(), Marshal.SizeOf(typeof(MIDIEVENT)));
                        gch.Free();
                        ptrOfs += baseEventSize;
                        ofs     = 0;
                    }
                    else
                    {
                        ofs = @event.Position;
                    }
                }
                else                 // sysex or sysex part
                {
                    byte[] data;
                    if (0 == @event.Message.Status)
                    {
                        data = (@event.Message as MidiMessageSysexPart).Data;
                    }
                    else
                    {
                        data = MidiUtility.ToMessageBytes(@event.Message);
                    }


                    var dl = data.Length;
                    if (0 != (dl % 4))
                    {
                        dl += 4 - (dl % 4);
                    }
                    if (_SendBufferSize < blockSize + baseEventSize + dl)
                    {
                        break;
                    }

                    blockSize += baseEventSize + dl;

                    var se = new MIDIEVENT();
                    se.dwDeltaTime = @event.Position + ofs;
                    se.dwStreamId  = 0;
                    se.dwEvent     = MEVT_F_LONG | data.Length;
                    var gch = GCHandle.Alloc(se, GCHandleType.Pinned);
                    CopyMemory(new IntPtr(ptrOfs + eventPointer.ToInt64()), gch.AddrOfPinnedObject(), Marshal.SizeOf(typeof(MIDIEVENT)));
                    gch.Free();
                    ptrOfs += baseEventSize;
                    Marshal.Copy(data, 0, new IntPtr(ptrOfs + eventPointer.ToInt64()), data.Length);

                    ptrOfs += dl;
                    ofs     = 0;
                }
            }
            _sendHeader = default(MIDIHDR);
            _sendHeader.dwBufferLength = _sendHeader.dwBytesRecorded = unchecked ((uint)blockSize);
            _sendHeader.lpData         = _sendEventBuffer;
            int headerSize = Marshal.SizeOf(typeof(MIDIHDR));

            _CheckOutResult(midiOutPrepareHeader(_handle, ref _sendHeader, headerSize));
            _CheckOutResult(midiStreamOut(_handle, ref _sendHeader, headerSize));
        }
Ejemplo n.º 32
0
 public static extern int midiInAddBuffer(int hMidiIN, ref MIDIHDR lpMidiInHdr, int uSize);
Ejemplo n.º 33
0
        /// <summary>
        /// Sends events directly to the event queue without buffering
        /// </summary>
        /// <param name="events">The events to send</param>
        /// <remarks>The total size of the events must be less than 64kb</remarks>
        public void SendDirect(IEnumerable <MidiEvent> events)
        {
            if (null == events)
            {
                throw new ArgumentNullException("events");
            }
            if (IntPtr.Zero == _handle)
            {
                throw new InvalidOperationException("The stream is closed.");
            }
            if (IntPtr.Zero != _sendHeader.lpData)
            {
                throw new InvalidOperationException("The stream is busy playing.");
            }
            int    baseEventSize = Marshal.SizeOf(typeof(MIDIEVENT));
            int    blockSize     = 0;
            IntPtr eventPointer  = _sendEventBuffer;
            var    ofs           = 0;
            var    ptrOfs        = 0;
            var    hasEvents     = false;

            foreach (var @event in events)
            {
                hasEvents = true;
                if (0xF0 != (@event.Message.Status & 0xF0))
                {
                    blockSize += baseEventSize;
                    if (_SendBufferSize <= blockSize)
                    {
                        throw new ArgumentException("There are too many events in the event buffer - maximum size must be 64k", "events");
                    }
                    var se = new MIDIEVENT();
                    se.dwDeltaTime = @event.Position + ofs;
                    se.dwStreamId  = 0;
                    se.dwEvent     = MidiUtility.PackMessage(@event.Message);
                    Marshal.StructureToPtr(se, new IntPtr(ptrOfs + eventPointer.ToInt64()), false);
                    ptrOfs += baseEventSize;
                    ofs     = 0;
                }
                else if (0xFF == @event.Message.Status)
                {
                    var mm = @event.Message as MidiMessageMeta;
                    if (0x51 == mm.Data1)                     // tempo
                    {
                        blockSize += baseEventSize;
                        if (_SendBufferSize <= blockSize)
                        {
                            throw new ArgumentException("There are too many events in the event buffer - maximum size must be 64k", "events");
                        }

                        var se = new MIDIEVENT();
                        se.dwDeltaTime = @event.Position + ofs;
                        se.dwStreamId  = 0;
                        se.dwEvent     = (mm.Data[0] << 16) | (mm.Data[1] << 8) | mm.Data[2] | (MEVT_TEMPO << 24);
                        Marshal.StructureToPtr(se, new IntPtr(ptrOfs + eventPointer.ToInt64()), false);
                        ptrOfs += baseEventSize;
                        ofs     = 0;
                        // TODO: This signal is sent too early. It should really wait until after the
                        // MEVT_TEMPO message is processed by the driver, but i have no easy way to
                        // do that. All we can do is hope, here
                        Interlocked.Exchange(ref _tempoSyncMessagesSentCount, 0);
                    }
                    else if (0x2f == mm.Data1)                     // end track
                    {
                        blockSize += baseEventSize;
                        if (_SendBufferSize <= blockSize)
                        {
                            throw new ArgumentException("There are too many events in the event buffer - maximum size must be 64k", "events");
                        }

                        // add a NOP message to it just to pad our output in case we're looping
                        var se = new MIDIEVENT();
                        se.dwDeltaTime = @event.Position + ofs;
                        se.dwStreamId  = 0;
                        se.dwEvent     = (MEVT_NOP << 24);
                        Marshal.StructureToPtr(se, new IntPtr(ptrOfs + eventPointer.ToInt64()), false);
                        ptrOfs += baseEventSize;
                        ofs     = 0;
                    }
                    else
                    {
                        ofs = @event.Position;
                    }
                }
                else                 // sysex
                {
                    var msx = @event.Message as MidiMessageSysex;
                    var dl  = msx.Data.Length + 1;
                    if (0 != (dl % 4))
                    {
                        dl += 4 - (dl % 4);
                    }
                    blockSize += baseEventSize + dl;
                    if (_SendBufferSize <= blockSize)
                    {
                        throw new ArgumentException("There are too many events in the event buffer - maximum size must be 64k", "events");
                    }

                    var se = new MIDIEVENT();
                    se.dwDeltaTime = @event.Position + ofs;
                    se.dwStreamId  = 0;
                    se.dwEvent     = MEVT_F_LONG | (msx.Data.Length + 1);
                    Marshal.StructureToPtr(se, new IntPtr(ptrOfs + eventPointer.ToInt64()), false);
                    ptrOfs += baseEventSize;
                    Marshal.WriteByte(new IntPtr(ptrOfs + eventPointer.ToInt64()), msx.Status);
                    Marshal.Copy(msx.Data, 0, new IntPtr(ptrOfs + eventPointer.ToInt64() + 1), msx.Data.Length);

                    ptrOfs += dl;
                    ofs     = 0;
                }
            }
            if (hasEvents)
            {
                _sendHeader = default(MIDIHDR);
                Interlocked.Exchange(ref _sendHeader.lpData, eventPointer);
                _sendHeader.dwBufferLength = _sendHeader.dwBytesRecorded = unchecked ((uint)blockSize);
                _sendEventBuffer           = eventPointer;
                int headerSize = Marshal.SizeOf(typeof(MIDIHDR));
                _CheckOutResult(midiOutPrepareHeader(_handle, ref _sendHeader, headerSize));
                _CheckOutResult(midiStreamOut(_handle, ref _sendHeader, headerSize));
            }
        }
Ejemplo n.º 34
0
 public static extern MmResult midiOutUnprepareHeader(IntPtr hMidiOut, [MarshalAs(UnmanagedType.Struct)] ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 35
0
 static extern int midiStreamOut(IntPtr handle, ref MIDIHDR lpMidiOutHdr, int uSize);
Ejemplo n.º 36
0
 public static extern MmResult midiInAddBuffer(IntPtr hMidiIn, [MarshalAs(UnmanagedType.Struct)] ref MIDIHDR lpMidiInHdr, int uSize);
Ejemplo n.º 37
0
 public static extern int midiOutUnprepareHeader(int hMidiOUT, ref MIDIHDR lpMidiOutHdr, int uSize);