Example #1
0
        /// <summary>
        /// Closes the MIDI out device
        /// </summary>
        /// <param name="disposing">True if called from Dispose</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                //if(disposing) Components.Dispose();

                if (SysexBufferHeaders.Length > 0)
                {
                    //  Reset in order to release any Sysex buffers
                    //  We can't Unprepare and free them until they are flushed out. Neither can we close the handle.
                    MmException.Try(MidiInterop.midiInReset(hMidiIn), "midiInReset");

                    //  Free up all created and allocated buffers for incoming Sysex messages
                    foreach (var lpHeader in SysexBufferHeaders)
                    {
                        MidiInterop.MIDIHDR hdr = (MidiInterop.MIDIHDR)Marshal.PtrToStructure(lpHeader, typeof(MidiInterop.MIDIHDR));
                        MmException.Try(MidiInterop.midiInUnprepareHeader(hMidiIn, lpHeader, Marshal.SizeOf(typeof(MidiInterop.MIDIHDR))), "midiInPrepareHeader");
                        Marshal.FreeHGlobal(hdr.lpData);
                        Marshal.FreeHGlobal(lpHeader);
                    }

                    //  Defensive protection against double disposal
                    SysexBufferHeaders = new IntPtr[0];
                }
                MidiInterop.midiInClose(hMidiIn);
            }
            disposed = true;
        }
Example #2
0
        private void Callback(IntPtr midiInHandle, MidiInterop.MidiInMessage message, IntPtr userData, IntPtr messageParameter1, IntPtr messageParameter2)
        {
            switch (message)
            {
            case MidiInterop.MidiInMessage.Open:
                // message Parameter 1 & 2 are not used
                break;

            case MidiInterop.MidiInMessage.Data:
                // parameter 1 is packed MIDI message
                // parameter 2 is milliseconds since MidiInStart
                if (MessageReceived != null)
                {
                    MessageReceived(this, new MidiInMessageEventArgs(messageParameter1.ToInt32(), messageParameter2.ToInt32()));
                }
                break;

            case MidiInterop.MidiInMessage.Error:
                // parameter 1 is invalid MIDI message
                if (ErrorReceived != null)
                {
                    ErrorReceived(this, new MidiInMessageEventArgs(messageParameter1.ToInt32(), messageParameter2.ToInt32()));
                }
                break;

            case MidiInterop.MidiInMessage.Close:
                // message Parameter 1 & 2 are not used
                break;

            case MidiInterop.MidiInMessage.LongData:
                // parameter 1 is pointer to MIDI header
                // parameter 2 is milliseconds since MidiInStart
                if (SysexMessageReceived != null)
                {
                    MidiInterop.MIDIHDR hdr = (MidiInterop.MIDIHDR)Marshal.PtrToStructure(messageParameter1, typeof(MidiInterop.MIDIHDR));

                    //  Copy the bytes received into an array so that the buffer is immediately available for re-use
                    var sysexBytes = new byte[hdr.dwBytesRecorded];
                    Marshal.Copy(hdr.lpData, sysexBytes, 0, hdr.dwBytesRecorded);

                    SysexMessageReceived(this, new MidiInSysexMessageEventArgs(sysexBytes, messageParameter2.ToInt32()));
                    //  Re-use the buffer - but not if we have no event handler registered as we are closing
                    MidiInterop.midiInAddBuffer(hMidiIn, messageParameter1, Marshal.SizeOf(typeof(MidiInterop.MIDIHDR)));
                }
                break;

            case MidiInterop.MidiInMessage.LongError:
                // parameter 1 is pointer to MIDI header
                // parameter 2 is milliseconds since MidiInStart
                break;

            case MidiInterop.MidiInMessage.MoreData:
                // parameter 1 is packed MIDI message
                // parameter 2 is milliseconds since MidiInStart
                break;
            }
        }
Example #3
0
        public void SendBuffer(byte[] byteBuffer)
        {
            MidiInterop.MIDIHDR midihdr = default(MidiInterop.MIDIHDR);
            midihdr.lpData = Marshal.AllocHGlobal(byteBuffer.Length);
            Marshal.Copy(byteBuffer, 0, midihdr.lpData, byteBuffer.Length);
            midihdr.dwBufferLength  = byteBuffer.Length;
            midihdr.dwBytesRecorded = byteBuffer.Length;
            int uSize = Marshal.SizeOf(midihdr);

            MidiInterop.midiOutPrepareHeader(this.hMidiOut, ref midihdr, uSize);
            MmResult mmResult = MidiInterop.midiOutLongMsg(this.hMidiOut, ref midihdr, uSize);

            if (mmResult != MmResult.NoError)
            {
                MidiInterop.midiOutUnprepareHeader(this.hMidiOut, ref midihdr, uSize);
            }
            Marshal.FreeHGlobal(midihdr.lpData);
        }
Example #4
0
        /// <summary>
        /// Send a long message, for example sysex.
        /// </summary>
        /// <param name="byteBuffer">The bytes to send.</param>
        public void SendBuffer(byte[] byteBuffer)
        {
            var header = new MidiInterop.MIDIHDR();

            header.lpData = Marshal.AllocHGlobal(byteBuffer.Length);
            Marshal.Copy(byteBuffer, 0, header.lpData, byteBuffer.Length);

            header.dwBufferLength  = byteBuffer.Length;
            header.dwBytesRecorded = byteBuffer.Length;
            int size = Marshal.SizeOf(header);

            MidiInterop.midiOutPrepareHeader(this.hMidiOut, ref header, size);
            var errcode = MidiInterop.midiOutLongMsg(this.hMidiOut, ref header, size);

            if (errcode != MmResult.NoError)
            {
                MidiInterop.midiOutUnprepareHeader(this.hMidiOut, ref header, size);
            }
            Marshal.FreeHGlobal(header.lpData);
        }
Example #5
0
        /// <summary>
        /// Create a number of buffers and make them available to receive incoming Sysex messages
        /// </summary>
        /// <param name="bufferSize">The size of each buffer, ideally large enough to hold a complete message from the device</param>
        /// <param name="numberOfBuffers">The number of buffers needed to handle incoming Midi while busy</param>
        public void CreateSysexBuffers(int bufferSize, int numberOfBuffers)
        {
            SysexBufferHeaders = new IntPtr[numberOfBuffers];

            var hdrSize = Marshal.SizeOf(typeof(MidiInterop.MIDIHDR));

            for (var i = 0; i < numberOfBuffers; i++)
            {
                var hdr = new MidiInterop.MIDIHDR();

                hdr.dwBufferLength  = bufferSize;
                hdr.dwBytesRecorded = 0;
                hdr.lpData          = Marshal.AllocHGlobal(bufferSize);
                hdr.dwFlags         = 0;

                var lpHeader = Marshal.AllocHGlobal(hdrSize);
                Marshal.StructureToPtr(hdr, lpHeader, false);

                MmException.Try(MidiInterop.midiInPrepareHeader(hMidiIn, lpHeader, Marshal.SizeOf(typeof(MidiInterop.MIDIHDR))), "midiInPrepareHeader");
                MmException.Try(MidiInterop.midiInAddBuffer(hMidiIn, lpHeader, Marshal.SizeOf(typeof(MidiInterop.MIDIHDR))), "midiInAddBuffer");
                SysexBufferHeaders[i] = lpHeader;
            }
        }
Example #6
0
 public static extern MmResult midiInUnprepareHeader(IntPtr hMidiIn, [MarshalAs(UnmanagedType.Struct)] ref MidiInterop.MIDIHDR lpMidiInHdr, int uSize);
Example #7
0
 public static extern MmResult midiStreamOut(IntPtr hMidiStream, [MarshalAs(UnmanagedType.Struct)] ref MidiInterop.MIDIHDR pmh, int cbmh);
Example #8
0
 public static extern MmResult midiOutLongMsg(IntPtr hMidiOut, [MarshalAs(UnmanagedType.Struct)] ref MidiInterop.MIDIHDR lpMidiOutHdr, int uSize);
Example #9
0
        /// <summary>
        /// Send a long message, for example sysex.
        /// </summary>
        /// <param name="byteBuffer">The bytes to send.</param>
        public void SendBuffer(byte[] byteBuffer)
        {
            var header = new MidiInterop.MIDIHDR();
            header.lpData = Marshal.AllocHGlobal(byteBuffer.Length);
            Marshal.Copy(byteBuffer, 0, header.lpData, byteBuffer.Length);

            header.dwBufferLength = byteBuffer.Length;
            header.dwBytesRecorded = byteBuffer.Length;
            int size = Marshal.SizeOf(header);
            MidiInterop.midiOutPrepareHeader(this.hMidiOut, ref header, size);
            var errcode = MidiInterop.midiOutLongMsg(this.hMidiOut, ref header, size);
            if (errcode != MmResult.NoError)
            {
                MidiInterop.midiOutUnprepareHeader(this.hMidiOut, ref header, size);
            }
            Marshal.FreeHGlobal(header.lpData);
        }