/// <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); }
/// <summary> /// Processes the provided <see cref="LongMessage"/> and raises associated events. /// </summary> /// <param name="message">A <see cref="LongMessage"/> to process and raise events for.</param> private void ProcessLongMessage(LongMessage message) { switch (message.ID) { case (int)UniversalSystemExclusiveMessageTypes.UniversalRealTime: UniversalRealTimeReceived?.Invoke(this, new UniversalRealTimeMessageEventArgs(new UniversalRealTimeMessage(message))); break; case (int)UniversalSystemExclusiveMessageTypes.UniversalNonRealTime: UniversalNonRealTimeReceived?.Invoke(this, new UniversalNonRealTimeMessageEventArgs(new UniversalNonRealTimeMessage(message))); break; default: SystemExclusiveReceived?.Invoke(this, new SystemExclusiveMessageEventArgs(new SystemExclusiveMessage(message))); break; } RecycleBuffer(message.ParameterA); }
/// <summary> /// Creates and initializes a <see cref="LongMessage"/> from the specified <see cref="UniversalRealTimeMessage"/>. /// </summary> /// <param name="message">A <see cref="LongMessage"/> to initilize the <see cref="UniversalRealTimeMessage"/> from.</param> internal UniversalRealTimeMessage(LongMessage message) : base(message) { }
/// <summary> /// Creates and initializes a <see cref="SystemExclusiveMessage"/> from the specified <see cref="LongMessage"/>. /// </summary> /// <param name="message">The <see cref="LongMessage"/> to initilize the <see cref="SystemExclusiveMessage"/> from.</param> internal SystemExclusiveMessage(LongMessage message) : base(message) { }
/// <summary> /// Internal constructor for conversion of <see cref="LongMessage"/> derived types inside the <see cref="MidiInputDevice.Callback"/> method. /// </summary> /// <param name="message">The <see cref="LongMessage"/> to create and initialize the derived type from.</param> internal LongMessage(LongMessage message) : this(message.ParameterA, message.ParameterB) { }