예제 #1
0
        /// <summary>
        /// Empties header queue.
        /// </summary>
        private void EmptyHeaderQueue()
        {
            IEnumerator en = syncHeaderQueue.GetEnumerator();

            // While there are still headers in the queue.
            while (en.MoveNext())
            {
                // Get header.
                MidiHeader header = (MidiHeader)en.Current;

                // Unprepare header.
                ThrowOnError(midiOutUnprepareHeader(handle, ref header,
                                                    Marshal.SizeOf(header)));

                // Free memory allocated for the system exclusive data.
                Marshal.FreeHGlobal(header.data);
            }

            // Clear queue.
            syncHeaderQueue.Clear();
        }
예제 #2
0
        /// <summary>
        /// Handles triggering the system exclusive message received event.
        /// </summary>
        /// <param name="header">
        /// Midi header containing the system exclusive message.
        /// </param>
        /// <param name="timeStamp">
        /// Number of milliseconds that have passed since the input device
        /// began recording.
        /// </param>
        private void DispatchSysExMessage(MidiHeader header, int timeStamp)
        {
            // Create array for holding system exclusive data.
            byte[] data = new byte[header.bytesRecorded - 1];

            // Get status byte.
            byte status = Marshal.ReadByte(header.data);

            // Copy system exclusive data into array (status byte is
            // excluded).
            for (int i = 1; i < header.bytesRecorded; i++)
            {
                data[i - 1] = Marshal.ReadByte(header.data, i);
            }

            // Create message.
            SysExMessage msg = new SysExMessage((SysExType)status, data);

            // Raise event.
            SysExReceived(this, new SysExEventArgs(msg, timeStamp));
        }
예제 #3
0
        /// <summary>
        /// Manages system exclusive messages received by the input device.
        /// </summary>
        /// <param name="param1">
        /// Integer pointer to the header containing the received system
        /// exclusive message.
        /// </param>
        /// <param name="timeStamp">
        /// Number of milliseconds that have passed since the input device
        /// began recording.
        /// </param>
        private void ManageSysExMessage(int param1, int timeStamp)
        {
            // Get pointer to header.
            IntPtr ptrHeader = new IntPtr(param1);

            // If anyone is listening for system exclusive messages.
            if (SysExReceived != null)
            {
                // Imprint raw pointer on to structure.
                MidiHeader header = (MidiHeader)Marshal.PtrToStructure(ptrHeader, typeof(MidiHeader));

                // Dispatches system exclusive messages.
                DispatchSysExMessage(header, timeStamp);
            }

            // Enqueue next system exclusive header and signal the worker queue
            // that another header is ready to be processed.
            lock (lockObject)
            {
                sysExHeaderQueue.Enqueue(ptrHeader);
                Monitor.Pulse(lockObject);
            }
        }
예제 #4
0
        /// <summary>
        /// Thread method for managing headers.
        /// </summary>
        private void ManageHeaders()
        {
            // While the device is open.
            while (IsOpen())
            {
                // Wait to be signalled when a header had finished being used.
                resetEvent.WaitOne();

                // While there are still headers in the queue.
                while (syncHeaderQueue.Count > 0)
                {
                    // Get header from the front of the queue.
                    MidiHeader header = (MidiHeader)syncHeaderQueue.Dequeue();

                    // Unprepare header.
                    int result = midiOutUnprepareHeader(handle, ref header,
                                                        Marshal.SizeOf(header));

                    // If an error occurred with unpreparing the system
                    // exclusive header.
                    if (result != MMSYSERR_NOERROR)
                    {
                        if (SysExHeaderErrorOccurred != null)
                        {
                            OutputDeviceException ex =
                                new OutputDeviceException(result);

                            SysExHeaderErrorOccurred(this,
                                                     new SysExHeaderErrorEventArgs(ex.Message));
                        }
                    }

                    // Free memory allocated for the system exclusive data.
                    Marshal.FreeHGlobal(header.data);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Sends system exclusive messages.
        /// </summary>
        /// <param name="message">
        /// The system exclusive message to send.
        /// </param>
        public void Send(SysExMessage message)
        {
            // Guard.
            if (!IsOpen())
            {
                return;
            }

            // Create header.
            MidiHeader header = new MidiHeader();

            // System exclusive message data.
            string msg = message.Message;

            //
            // Initialize header.
            //

            header.data         = Marshal.StringToHGlobalAnsi(msg);
            header.bufferLength = msg.Length;
            header.flags        = 0;

            // Prepare header.
            ThrowOnError(midiOutPrepareHeader(handle, ref header,
                                              Marshal.SizeOf(header)));

            // Place header in queue to be retrieved later.
            syncHeaderQueue.Enqueue(header);

            // Send message.
            ThrowOnError(midiOutLongMsg(handle, ref header,
                                        Marshal.SizeOf(header)));

            // System exclusive messages cancel running status.
            runningStatus = 0;
        }
예제 #6
0
 private static extern int midiOutUnprepareHeader(int handle, 
     ref MidiHeader midiHeader, int sizeOfmidiHeader);
예제 #7
0
 private static extern int midiOutLongMsg(int handle, 
     ref MidiHeader midiHeader, int sizeOfmidiHeader);
예제 #8
0
        /// <summary>
        /// Sends system exclusive messages.
        /// </summary>
        /// <param name="message">
        /// The system exclusive message to send.
        /// </param>
        public void Send(SysExMessage message)
        {
            // Guard.
            if(!IsOpen())
                return;

            // Create header.
            MidiHeader header = new MidiHeader();

            // System exclusive message data.
            string msg = message.Message;

            //
            // Initialize header.
            //

            header.data = Marshal.StringToHGlobalAnsi(msg);
            header.bufferLength = msg.Length;
            header.flags = 0;

            // Prepare header.
            ThrowOnError(midiOutPrepareHeader(handle, ref header,
                Marshal.SizeOf(header)));

            // Place header in queue to be retrieved later.
            syncHeaderQueue.Enqueue(header);

            // Send message.
            ThrowOnError(midiOutLongMsg(handle, ref header,
                Marshal.SizeOf(header)));

            // System exclusive messages cancel running status.
            runningStatus = 0;
        }
예제 #9
0
 private static extern int midiOutLongMsg(int handle,
                                          ref MidiHeader midiHeader, int sizeOfmidiHeader);
예제 #10
0
 private static extern int midiOutUnprepareHeader(int handle,
                                                  ref MidiHeader midiHeader, int sizeOfmidiHeader);
예제 #11
0
        /// <summary>
        /// Handles triggering the system exclusive message received event.
        /// </summary>
        /// <param name="header">
        /// Midi header containing the system exclusive message.
        /// </param>
        /// <param name="timeStamp">
        /// Number of milliseconds that have passed since the input device 
        /// began recording.
        /// </param>
        private void DispatchSysExMessage(MidiHeader header, int timeStamp)
        {
            // Create array for holding system exclusive data.
            byte[] data = new byte[header.bytesRecorded - 1];

            // Get status byte.
            byte status = Marshal.ReadByte(header.data);

            // Copy system exclusive data into array (status byte is
            // excluded).
            for(int i = 1; i < header.bytesRecorded; i++)
            {
                data[i - 1] = Marshal.ReadByte(header.data, i);
            }

            // Create message.
            SysExMessage msg = new SysExMessage((SysExType)status, data);

            // Raise event.
            SysExReceived(this, new SysExEventArgs(msg, timeStamp));
        }