源代码:运行通过验证的:http://download.csdn.net/detail/tianjun2012/6574171(不需要的直接看下面)
第一步:(本例子,我原代码可是利用Samson carbon49实验的,(从无到有)花了2个星期……无语)
首先我们得了解在windows系统中获取消息的方式,我们不管搞不搞底层编程肯定都知道驱动这个概念(如果不知道百度或者谷歌去)外设的消息首先是发送到发现它的驱动上去,我们利用Windows API从驱动中把消息取出来就可以了,首先肯定我们想到的是去写个驱动,这个很对,但是如果你对通信或者是底层编程没啥基础,还是不要去浪费时间了,万幸的是万恶的微软一般的常用的工种USB的驱动都集成着有,所以不用去太话费时间了,我们只需要利用API读取就行了。
第二步:
我们得对c#中对Windows API的引用“DLLImport”关键字,不知道的MSDN上查具体用法,言归正传,我们调用Windows API,代码例子如下:
internal static class NativeMethods
{
internal const int MMSYSERR_NOERROR = 0;
internal const int CALLBACK_FUNCTION = 0x00030000;
internal delegate void MidiInProc(
IntPtr hMidiIn,
uint wMsg,
IntPtr dwInstance,
UInt32 dwParam1,
UInt32 dwParam2);
[DllImport("winmm.dll")]
internal static extern int midiInGetNumDevs();
[DllImport("winmm.dll")]
internal static extern int midiInClose(
IntPtr hMidiIn);
[DllImport("winmm.dll")]
internal static extern int midiInOpen(
out IntPtr lphMidiIn,
int uDeviceID,
MidiInProc dwCallback,
IntPtr dwCallbackInstance,
int dwFlags);
[DllImport("winmm.dll")]
internal static extern int midiInStart(
IntPtr hMidiIn);
[DllImport("winmm.dll")]
internal static extern int midiInStop(
IntPtr hMidiIn);
}
第三步:
对上述API的运用(多话不说,原代码奉上)
public class InputPort
{
private NativeMethods.MidiInProc midiInProc;
private IntPtr handle;
public InputPort()
{
midiInProc = new NativeMethods.MidiInProc(MidiProc);
handle = IntPtr.Zero;
}
public static int InputCount
{
get { return NativeMethods.midiInGetNumDevs(); }
}
public bool Close()
{
bool result = NativeMethods.midiInClose(handle)
== NativeMethods.MMSYSERR_NOERROR;
handle = IntPtr.Zero;
return result;
}
public bool Open(int id)
{
return NativeMethods.midiInOpen(
out handle,
id,
midiInProc,
IntPtr.Zero,
NativeMethods.CALLBACK_FUNCTION)
== NativeMethods.MMSYSERR_NOERROR;
}
public bool Start()
{
return NativeMethods.midiInStart(handle)
== NativeMethods.MMSYSERR_NOERROR;
}
public bool Stop()
{
return NativeMethods.midiInStop(handle)
== NativeMethods.MMSYSERR_NOERROR;
}
public IntPtr hmidi = IntPtr.Zero;
public uint midi_wMsg = 0;
public IntPtr midi_dwIns = IntPtr.Zero;
public UInt32 midi_dw1 = 0;
public UInt32 mide_dw2 = 0;
public void MidiProc(IntPtr hMidiIn,
uint wMsg,
IntPtr dwInstance,
UInt32 dwParam1,
UInt32 dwParam2)
{
// Receive messages here
hmidi = hMidiIn;
if (wMsg == 963)
{
dwParam1 = dwParam1 & 0xFFFF;
uint h_dw1 = 0;
uint l_dw1 = 0;
h_dw1 = dwParam1 & 0xFF;
l_dw1 = (dwParam1 >> 8) & 0xFF;
Console.WriteLine(Convert.ToString(wMsg, 16));
Console.WriteLine(Convert.ToString(h_dw1, 16));
Console.WriteLine(Convert.ToString(l_dw1, 16));
Console.WriteLine(Convert.ToString(dwParam2, 16));
Console.WriteLine("-------------------------------");
}
else
{
Console.WriteLine(Convert.ToString(wMsg, 16));
Console.WriteLine(Convert.ToString(dwParam1, 16));
Console.WriteLine(Convert.ToString(dwParam2, 16));
Console.WriteLine("-------------------------------");
}
}
}
第四步:
你在你的主函数中运用就行了,注意啊,那个MidiProc(IntPtr hMidiIn,uint wMsg,IntPtr dwInstance, UInt32 dwParam1,UInt32 dwParam2)系统会自动调用它去获取MIDI消息,不用你在写个函数去循环获取消息了,具体的demo,我会传到上去的,等下我发个链接。
第五步:
得感谢这个老外啊,你们也可以参考下:http://stackoverflow.com/questions/1991159/getting-signals-from-a-midi-port-in-c-sharp/1992014#1992014
MIDI APID的读取,大家参考MSDN:http://msdn.microsoft.com/en-us/library/windows/desktop/dd798495(v=vs.85).aspx
当然这只是最简单的MIDI消息的读取,还有USB的其他设备,我给大家几个链接,
http://www.codeproject.com/Articles/18099/A-USB-HID-Component-for-C
http://www.developerfusion.com/article/84338/making-usb-c-friendly/
(太感谢这些无私的老外们了)