Exemplo n.º 1
0
        /// <summary>
        /// Creates and initializes a <see cref="LongMessage"/>, for use inside the <see cref="MidiInputDevice.Callback"/> method.
        /// </summary>
        /// <param name="messageParameterA">An <see cref="IntPtr"/> to store a reference to the first message parameter.</param>
        /// <param name="messageParameterB">An <see cref="IntPtr"/> to store a reference to the second message parameter.</param>
        internal LongMessage(IntPtr messageParameterA, IntPtr messageParameterB)
        {
            // Set the pointer to the MIDI header structure (Converted from UIntPtr to IntPtr)
            _MidiHeaderPointer = unchecked ((IntPtr)(long)(ulong)messageParameterA);

            // Create a managed copy of the MIDI header
            _MidiHeader = (API.MidiHeader)Marshal.PtrToStructure(_MidiHeaderPointer, typeof(API.MidiHeader));

            // Create the data array with the size of the long message
            this.Data = new byte[_MidiHeader.BytesRecorded];

            // Fill the data array by looping through the MIDI header data
            for (int i = 0; i < _MidiHeader.BytesRecorded; i++)
            {
                this.Data[i] = Marshal.ReadByte(_MidiHeader.Data, i);
            }

            // Extract the ID byte
            this.ID = this.Data[1];

            // Extract message parameter B
            this.TimeStamp = (int)messageParameterB;

            // Set the parameter references
            this.ParameterA = messageParameterA;
            this.ParameterB = messageParameterB;
        }
Exemplo n.º 2
0
        private void Dispose(bool disposing)
        {
            if (!_IsDisposed)
            {
                if (disposing)
                {
                    // TODO: dispose managed state (managed objects)
                }

                if (_Buffer.Count > 0)
                {
                    API.ResetMidiInputDevice(_Handle);

                    foreach (var headerPointer in _Buffer)
                    {
                        API.MidiHeader header = (API.MidiHeader)Marshal.PtrToStructure(headerPointer, typeof(API.MidiHeader));
                        API.UnprepareMidiInputHeader(_Handle, headerPointer, Marshal.SizeOf(typeof(API.MidiHeader)));
                        Marshal.FreeHGlobal(header.Data);
                        Marshal.FreeHGlobal(headerPointer);
                    }
                }

                API.CloseMidiInputDevice(_Handle);

                // TODO: free unmanaged resources (unmanaged objects) and override finalizer
                // TODO: set large fields to null
                _IsDisposed = true;
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Callback function to be called by the system.
        /// </summary>
        /// <param name="handle">An <see cref="API.MidiDeviceHandle"/> to the MIDI input device to associate with the callback function.</param>
        /// <param name="message">An <see cref="API.MidiInputMessage"/> containing the message.</param>
        /// <param name="instance">An <see cref="IntPtr"/> to the instance data supplied by the <see cref="API.OpenMidiInputDevice"/> function.</param>
        /// <param name="messageParameterA">An <see cref="IntPtr"/> to the first message parameter.</param>
        /// <param name="messageParameterB">An <see cref="IntPtr"/> to the second message parameter.</param>
        private void Callback(API.MidiDeviceHandle handle, API.MidiInputMessage message, IntPtr instance, IntPtr messageParameterA, IntPtr messageParameterB)
        {
            switch (message)
            {
            case API.MidiInputMessage.MIDI_INPUT_MESSAGE_DATA:

                // A = Packed MIDI message, B = Time in milliseconds since Start
                ProcessShortMessage(new ShortMessage(messageParameterA, messageParameterB));

                break;

            case API.MidiInputMessage.MIDI_INPUT_MESSAGE_LONG_DATA:

                // Extracts the MIDI header for message validation
                API.MidiHeader midiHeader = (API.MidiHeader)Marshal.PtrToStructure(messageParameterA, typeof(API.MidiHeader));

                // Prevents creation of long messages when the MIDI header buffer is empty
                if (midiHeader.BytesRecorded == 0)
                {
                    ReleaseBuffer(messageParameterA);
                    return;
                }

                // A = Pointer to MIDI header, B = Time in milliseconds since Start
                ProcessLongMessage(new LongMessage(messageParameterA, messageParameterB));

                break;

            case API.MidiInputMessage.MIDI_INPUT_MESSAGE_MORE_DATA:
                Console.WriteLine("MIDI IN MORE DATA");
                // A = Packed MIDI message, B = Time in milliseconds since Start
                break;

            case API.MidiInputMessage.MIDI_INPUT_MESSAGE_ERROR:

                // A = Invalid MIDI message, B = Time in milliseconds since Start
                break;

            case API.MidiInputMessage.MIDI_INPUT_MESSAGE_LONG_ERROR:

                // A = Pointer to MIDI header, B = Time in milliseconds since Start
                break;

            case API.MidiInputMessage.MIDI_INPUT_MESSAGE_OPEN:

                this.IsOpen = true;

                break;

            case API.MidiInputMessage.MIDI_INPUT_MESSAGE_CLOSE:

                this.IsOpen = false;

                break;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Releases an existing buffer and associated memory.
        /// </summary>
        /// <param name="buffer">An <see cref="IntPtr"/> referencing the buffer to release.</param>
        /// <exception cref="MidiInputDeviceException">Raises <see cref="API.Result.MULTIMEDIA_SYSTEM_ERROR_INVALID_HANDLE"/>.</exception>
        /// <exception cref="MidiInputDeviceException">Raises <see cref="API.Result.MULTIMEDIA_SYSTEM_ERROR_INVALID_PARAMETER"/>.</exception>
        /// <exception cref="MidiInputDeviceException">Raises <see cref="API.Result.MIDI_ERROR_STILL_PLAYING"/>.</exception>
        private void ReleaseBuffer(IntPtr buffer)
        {
            IntPtr headerPointer = unchecked ((IntPtr)(long)(ulong)buffer);
            int    headerSize    = Marshal.SizeOf(typeof(API.MidiHeader));

            InvalidateResult(API.UnprepareMidiInputHeader(_Handle, headerPointer, headerSize));

            API.MidiHeader midiHeader = (API.MidiHeader)Marshal.PtrToStructure(headerPointer, typeof(API.MidiHeader));

            Marshal.FreeHGlobal(midiHeader.Data);
            Marshal.FreeHGlobal(headerPointer);

            _Buffer.Remove(headerPointer);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Sends a long MIDI message.
        /// </summary>
        /// <param name="message">The long MIDI message to send.</param>
        /// <exception cref="MidiOutputDeviceException">Raises <see cref="API.Result.MULTIMEDIA_SYSTEM_ERROR_INVALID_HANDLE"/>.</exception>
        /// <exception cref="MidiOutputDeviceException">Raises <see cref="API.Result.MULTIMEDIA_SYSTEM_ERROR_NO_MEM"/>.</exception>
        /// <exception cref="MidiOutputDeviceException">Raises <see cref="API.Result.MULTIMEDIA_SYSTEM_ERROR_INVALID_PARAMETER"/>.</exception>
        /// <exception cref="MidiOutputDeviceException">Raises <see cref="API.Result.MIDI_ERROR_UNPREPARED"/>.</exception>
        /// <exception cref="MidiOutputDeviceException">Raises <see cref="API.Result.MIDI_ERROR_STILL_PLAYING"/>.</exception>
        /// <exception cref="MidiOutputDeviceException">Raises <see cref="API.Result.MIDI_ERROR_NOT_READY"/>.</exception>
        public void Send(LongMessage message)
        {
            IntPtr midiHeaderPointer;

            int midiHeaderSize = Marshal.SizeOf(typeof(API.MidiHeader));

            API.MidiHeader midiHeader = new API.MidiHeader();

            midiHeader.Data = Marshal.AllocHGlobal(message.Data.Length);

            for (int i = 0; i < message.Data.Length; i++)
            {
                Marshal.WriteByte(midiHeader.Data, i, message.Data[i]);
            }

            midiHeader.BufferSize    = message.Data.Length;
            midiHeader.BytesRecorded = message.Data.Length;
            midiHeader.Flags         = 0;

            try
            {
                midiHeaderPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(API.MidiHeader)));
            }
            catch (Exception)
            {
                Marshal.FreeHGlobal(midiHeader.Data);
                throw;
            }

            try
            {
                Marshal.StructureToPtr(midiHeader, midiHeaderPointer, false);
            }
            catch (Exception)
            {
                Marshal.FreeHGlobal(midiHeader.Data);
                Marshal.FreeHGlobal(midiHeaderPointer);
                throw;
            }

            InvalidateResult(API.PrepareMidiOutputHeader(_Handle, midiHeaderPointer, midiHeaderSize));
            InvalidateResult(API.SendLongMessage(_Handle, midiHeaderPointer, midiHeaderSize));
            InvalidateResult(API.UnprepareMidiOutputHeader(_Handle, midiHeaderPointer, midiHeaderSize));

            Marshal.FreeHGlobal(midiHeader.Data);
            Marshal.FreeHGlobal(midiHeaderPointer);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Creates a buffer for receiving <see cref="LongMessage"/>s.
        /// </summary>
        /// <returns>An <see cref="IntPtr"/> referencing the created buffer.</returns>
        /// <exception cref="MidiInputDeviceException">Raises <see cref="API.Result.MULTIMEDIA_SYSTEM_ERROR_INVALID_HANDLE"/>.</exception>
        /// <exception cref="MidiInputDeviceException">Raises <see cref="API.Result.MULTIMEDIA_SYSTEM_ERROR_NO_MEM"/>.</exception>
        /// <exception cref="MidiInputDeviceException">Raises <see cref="API.Result.MULTIMEDIA_SYSTEM_ERROR_INVALID_PARAMETER"/>.</exception>
        /// <exception cref="MidiInputDeviceException">Raises <see cref="API.Result.MIDI_ERROR_UNPREPARED"/>.</exception>
        /// <exception cref="MidiInputDeviceException">Raises <see cref="API.Result.MIDI_ERROR_STILL_PLAYING"/>.</exception>
        private IntPtr CreateBuffer()
        {
            IntPtr midiHeaderPointer;

            int headerSize = Marshal.SizeOf(typeof(API.MidiHeader));

            API.MidiHeader midiHeader = new API.MidiHeader();

            // TODO: Optimize buffer size
            midiHeader.Data       = Marshal.AllocHGlobal(256);
            midiHeader.BufferSize = 256;
            midiHeader.Flags      = 0;

            try
            {
                midiHeaderPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(API.MidiHeader)));
            }
            catch (Exception)
            {
                Marshal.FreeHGlobal(midiHeader.Data);
                throw;
            }

            try
            {
                Marshal.StructureToPtr(midiHeader, midiHeaderPointer, false);
            }
            catch (Exception)
            {
                Marshal.FreeHGlobal(midiHeader.Data);
                Marshal.FreeHGlobal(midiHeaderPointer);
                throw;
            }

            InvalidateResult(API.PrepareMidiInputHeader(_Handle, midiHeaderPointer, headerSize));
            InvalidateResult(API.AddMidiInputBuffer(_Handle, midiHeaderPointer, headerSize));

            return(midiHeaderPointer);
        }