/// <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; }
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; } }
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); }
/// <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); }
/// <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; } }
public static extern MmResult midiInUnprepareHeader(IntPtr hMidiIn, [MarshalAs(UnmanagedType.Struct)] ref MidiInterop.MIDIHDR lpMidiInHdr, int uSize);
public static extern MmResult midiStreamOut(IntPtr hMidiStream, [MarshalAs(UnmanagedType.Struct)] ref MidiInterop.MIDIHDR pmh, int cbmh);
public static extern MmResult midiOutLongMsg(IntPtr hMidiOut, [MarshalAs(UnmanagedType.Struct)] ref MidiInterop.MIDIHDR lpMidiOutHdr, int uSize);
/// <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); }