public string Open()
        {
            // Open the port
            var st = AlsaNativeMethods.Snd_rawmidi_open_input(
                ref handle, IntPtr.Zero, Device, AlsaNativeMethods.EMode.SND_RAWMIDI_NONBLOCK);

            return(AlsaUtils.StrError(st));
        }
        public string Start()
        {
            int st = (int)AlsaNativeMethods.Snd_rawmidi_read(handle, null, 0);

            if (st == 0)
            {
                stop       = false;
                readThread = new Thread(ReadThreadStart);
                readThread.Start();
            }
            return(AlsaUtils.StrError(st));
        }
        public string Close()
        {
            int st = 0;

            if (handle != IntPtr.Zero)
            {
                st     = AlsaNativeMethods.Snd_rawmidi_close(handle);
                handle = IntPtr.Zero;
            }

            return(AlsaUtils.StrError(st));
        }
Beispiel #4
0
        // Send a message
        public string Send(MidiMessage m)
        {
            byte[] data = m.GetAsByteArray();

            // Meta messages are not sent over the wire
            if (data == null)
            {
                return(null);
            }

            ulong size = (ulong)data.Length;

            long st = AlsaNativeMethods.Snd_rawmidi_write(handle, data, size);

            return(AlsaUtils.StrError((int)st));
        }
        private void ReadThreadStart()
        {
            byte[] buf         = new byte[512];
            byte[] overflowBuf = null;

            // Compute number of pollfd structures required to poll
            int numPollStructs = AlsaNativeMethods.Snd_rawmidi_poll_descriptors_count(handle);

            // Allocate space for the poll structures
            IntPtr pollAreaPtr = Marshal.AllocHGlobal(numPollStructs * AlsaNativeMethods.POLLFDSZ);

            int st = AlsaNativeMethods.Snd_rawmidi_poll_descriptors(handle, pollAreaPtr, (uint)numPollStructs);

            while (!stop)
            {
                st = AlsaNativeMethods.Poll(pollAreaPtr, numPollStructs, 200);
                if (st < 0)
                {
                    var errno = Marshal.GetLastWin32Error();
                    if (errno == 4 /* EINTR */)
                    {
                        continue;
                    }
                    Console.WriteLine("MidiIn: Cannot poll - errno = " + errno);
                    break;
                }
                if (st == 0)
                {
                    continue;
                }

                // We got something - scan the poll struct
                ushort revent = 0;
                st = AlsaNativeMethods.Snd_rawmidi_poll_descriptors_revents(
                    handle, pollAreaPtr, (uint)numPollStructs, ref revent);

                if (st < 0)
                {
                    Console.WriteLine("MidiIn: Cannot parse poll - " + AlsaUtils.StrError(st));
                    break;
                }

                AlsaNativeMethods.EPoll evt = (AlsaNativeMethods.EPoll)revent;
                if (evt.HasFlag(AlsaNativeMethods.EPoll.POLLERR) ||
                    evt.HasFlag(AlsaNativeMethods.EPoll.POLLHUP))
                {
                    break;
                }

                if (evt.HasFlag(AlsaNativeMethods.EPoll.POLLIN))
                {
                    // We have something to read - read it
                    int nRead = (int)AlsaNativeMethods.Snd_rawmidi_read(handle, buf, (uint)buf.Length);
                    if (nRead < 0)
                    {
                        int errno = Marshal.GetLastWin32Error();
                        if (errno == 4 /* EINTR */)
                        {
                            continue;
                        }

                        Console.WriteLine("MidiIn: Cannot parse poll - " + AlsaUtils.StrError(st));
                        break;
                    }

                    // Combine with overflow buffer if we had an overflow last time
                    if (overflowBuf != null)
                    {
                        var newBuf = new byte[buf.Length + overflowBuf.Length];
                        Array.Copy(overflowBuf, 0, newBuf, 0, overflowBuf.Length);
                        Array.Copy(buf, 0, newBuf, overflowBuf.Length, buf.Length);
                        buf         = newBuf;
                        overflowBuf = null;
                    }

                    // Translate the input to midi message
                    int nParsed = 0;
                    while (true)
                    {
                        st = ParseBuffer(buf, nParsed, nRead, out MidiMessage midiMessage);
                        if (st < 0)
                        {
                            // buffer contains an incomplete message
                            overflowBuf = buf;
                            buf         = new byte[overflowBuf.Length];
                        }
                        else if (st == 0)
                        {
                            // Message not supported - drop everything.
                            break;
                        }
                        else // st > 0
                        {
                            // Send message
                            var midiEvent    = new MidiEvent(midiMessage, 0);
                            var midiEventArg = new WindowsMultiMedia.WindowsMidiEventArgs(midiEvent, IntPtr.Zero, IntPtr.Zero);
                            MidiInputReceived?.Invoke(this, midiEventArg);

                            // Update counters
                            nParsed += st;
                            nRead   -= st;

                            if (nRead <= 0)
                            {
                                // Normal end
                                break;
                            }
                        }
                    }
                }
            }

            Marshal.FreeHGlobal(pollAreaPtr);
        }
        public string Reset()
        {
            int st = AlsaNativeMethods.Snd_rawmidi_drop(handle);

            return(AlsaUtils.StrError(st));
        }