C# 在C语言中从MIDI端口获取信号#

C# 在C语言中从MIDI端口获取信号#,c#,midi,C#,Midi,我买了一个MIDI键盘作为生日礼物。我发现了一个程序(MIDIPano),可以从MIDI输入中获取信号并将其转换为音乐,但我更愿意自己编写一个 在哪里可以找到执行此任务的文档?MIDI协议有很好的文档记录,但MIDI端口没有 我检查了CodeProject中的两个项目(projectmidi和C#MIDI工具包),但是花了很多时间没有接近我的目标 参考一个项目是可以的,但是请,只有C#。我也找不到太多,但是就像Josh说的,Carl确实在MIDI上做了很多工作,所以可能给他发一封电子邮件。。。他

我买了一个MIDI键盘作为生日礼物。我发现了一个程序(MIDIPano),可以从MIDI输入中获取信号并将其转换为音乐,但我更愿意自己编写一个

在哪里可以找到执行此任务的文档?MIDI协议有很好的文档记录,但MIDI端口没有

我检查了CodeProject中的两个项目(projectmidi和C#MIDI工具包),但是花了很多时间没有接近我的目标


参考一个项目是可以的,但是请,只有C#。

我也找不到太多,但是就像Josh说的,Carl确实在MIDI上做了很多工作,所以可能给他发一封电子邮件。。。他甚至可能会回答,但他通常是一个VB.Net的家伙,所以除非有人把他的东西移植到C#

对于其他一些看起来很有希望的参考资料

如果您正在寻找纯C#解决方案。。。看一看。它看起来确实有点高端,但可能会有所帮助


也可能

您需要包装上列出的所有所需函数

如果您只是使用短消息,这并不太困难,如果您想使用SysEx或输出流,事情会变得更加复杂

基本输入端口所需的只是获取有效的输入ID(InputCount-1),传递有效ID以打开,启动输入,通过委托接收消息。。。停止输入,然后最后关闭它。这是一个非常粗略的例子,说明了如何实现这一点-您需要进行一些检查,并小心在端口关闭和关闭回调发生之前未收集端口,否则将冻结系统

祝你好运

namespace MIDI { 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; } private void MidiProc(IntPtr hMidiIn, int wMsg, IntPtr dwInstance, int dwParam1, int dwParam2) { // Receive messages here } } internal static class NativeMethods { internal const int MMSYSERR_NOERROR = 0; internal const int CALLBACK_FUNCTION = 0x00030000; internal delegate void MidiInProc( IntPtr hMidiIn, int wMsg, IntPtr dwInstance, int dwParam1, int 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); } } 名称空间MIDI { 公共类输入端口 { private NativeMethods.midinproc midinproc; 私有IntPtr句柄; 公共输入端口() { midinproc=新的NativeMethods.midinproc(MidiProc); handle=IntPtr.Zero; } 公共静态整数输入计数 { get{return NativeMethods.MidingETNumDevs();} } 公共图书馆关闭() { bool result=NativeMethods.midiInClose(句柄) ==NativeMethods.MMSYSERR\u NOERROR; handle=IntPtr.Zero; 返回结果; } 公共布尔开放(内部id) { return NativeMethods.midinOpen( 出格, 身份证件 Midinproc, IntPtr.Zero, NativeMethods.CALLBACK(函数) ==NativeMethods.MMSYSERR\u NOERROR; } 公共bool Start() { 返回NativeMethods.midiInStart(句柄) ==NativeMethods.MMSYSERR\u NOERROR; } 公共车站 { 返回NativeMethods.midinStop(句柄) ==NativeMethods.MMSYSERR\u NOERROR; } 私有无效MidiProc(IntPtr hMidiIn, int wMsg, IntPtr, int dwParam1, int dwParam2) { //在此处接收消息 } } 内部静态类NativeMethods { 内部常量int MMSYSERR_NOERROR=0; 内部常量int回调函数=0x00030000; 内部委托无效MIDINPROC( IntPtr hMidiIn, int wMsg, IntPtr, int dwParam1, int dwParam2); [DllImport(“winmm.dll”)] 内部静态外部int midinGetNumDevs(); [DllImport(“winmm.dll”)] 内部静态外部内部包含( IntPtr-hmidii); [DllImport(“winmm.dll”)] 内部静态外部输入MIDINOPEN( 输出IntPtr lphMidiIn, 国际货币基金组织, MidinProc dwCallback, IntPtr dwCallbackInstance, int dwFlags); [DllImport(“winmm.dll”)] 内部静态外部内部安装( IntPtr-hmidii); [DllImport(“winmm.dll”)] 内部静态外部int midinstop( IntPtr-hmidii); } } 使用C#Midi工具包从键盘(连接到声卡的Midi输入端口)接收Midi信息。要创建音频(音乐或音调),您需要生成连续的数字音频数据流。您可以从C#Synth工具包(与midi工具包的作者相同)开始编写自己的Synth


但是你也可以下载一个免费的(开源的)sequencer程序(比如audacity)并使用VST仪器插件来完成这项工作。网络上有很多免费插件。

我正在开发c#midi通信系统。Sanford的midi工具包很好,但Leslie实现有很多改进,这使得代码可读性降低。我的代码尽可能简单。如果你愿意,你可以加入我。几天后,我发布了完全可以工作的midi监视器。看看

我以一种迂回的方式解决了这个问题,每次MIDI键盘上出现音符开/关时,我都会编写一个Python脚本来传输UDP数据包

通过这种方式包装特定于平台的MIDI内容,我可以编写平台无关的C代码来提取UDP数据包。

使用此代码,您可以从MIDI端口获取事件:

名称空间输入设备示例
{
班级计划
{
专用静态IIInputDevice\u inputDevice;
静态void Main(字符串[]参数)
{
_inputDevice=inputDevice.GetByName(“一些MIDI设备”);
_inputDevice.EventReceived+=OnEventReceived;
_inputDevice.StarteEventsListening();
Console.WriteLine(“输入设备正在侦听事件。按任意键退出…”);
Console.ReadKey();
(_inputDevice作为IDisposable)?.Dispose();
}
私有静态无效OnEventReceived(对象发送方,MidiEventReceivedEventArgs e)
{
变量midiDevice=(midiDevice)发送方;