我为我的生日买了一个MIDI键盘。我找到了一个程序(MidiPiano),它从MIDI输入中获取信号并将其转换为音乐,但我更愿意自己写一个。
我在哪里可以找到执行此类任务的文档? MIDI协议有很好的记录,但不是MIDI端口。
我从CodeProject(Project MIDI和C#MIDI Toolkit)检查了两个项目,但是花了很多时间没有接近我的目标。
对项目的引用会很好,但是请只有C#。
答案 0 :(得分:6)
您需要包含http://msdn.microsoft.com/en-us/library/dd757277(VS.85).aspx
中列出的所有必需功能如果您只是使用短消息并不太难,如果您想要进行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); } }
答案 1 :(得分:2)
我也找不到多少,但就像Josh说的那样,Carl肯定在MIDI上做过相当多的工作,所以也许给他一个电子邮件......他甚至可以回复,但他通常是VB.Net除非有人将他的东西移植到C#,否则这个人呢?
对于一些看起来很有希望的其他参考资料......
如果您正在寻找纯粹的C#解决方案......请查看Alvas.Audio。它确实看起来有点高端,但可能会有所帮助。
答案 2 :(得分:2)
我正在开发c#midi通信系统的过程。 Sanford的midi工具包很好,但Leslie的实现有许多改进,使代码的可读性降低。我的代码尽可能简单。如果你想要你可以加入我。几天后,我发布了完全工作的midi监视器。只需查看http://puremidi.codeplex.com/
即可答案 3 :(得分:1)
使用C#Midi Toolkit从键盘接收midi信息(连接到音频卡的midi输入端口)。要创建音频(音乐或音调),您需要生成连续的数字音频数据流。您可以从C#Synth Toolkit(与midi工具包相同的作者)开始编写您自己的合成器。
但你也可以下载一个免费的(开源)音序器程序(例如大胆)并使用VST乐器插件为你完成这项工作。网上有很多免费插件。
答案 4 :(得分:0)
我已经通过编写Python脚本来解决这个问题,每次在MIDI键盘上发生音符开/关时都会发送UDP数据包。
MIDI over TCP/IP/UDP to be received inUnity3D with C#/.NET
这样平台特定的MIDI内容被包装,我可以编写平台无关的C#代码来获取UDP数据包。
答案 5 :(得分:0)
使用DryWetMIDI,您可以使用以下代码从MIDI端口获取事件:
namespace InputDeviceExample
{
class Program
{
private static IInputDevice _inputDevice;
static void Main(string[] args)
{
_inputDevice = InputDevice.GetByName("Some MIDI device");
_inputDevice.EventReceived += OnEventReceived;
_inputDevice.StartEventsListening();
Console.WriteLine("Input device is listening for events. Press any key to exit...");
Console.ReadKey();
(_inputDevice as IDisposable)?.Dispose();
}
private static void OnEventReceived(object sender, MidiEventReceivedEventArgs e)
{
var midiDevice = (MidiDevice)sender;
Console.WriteLine($"Event received from '{midiDevice.Name}' at {DateTime.Now}: {e.Event}");
}
}
}
您可以在库文档的Devices部分中找到更多信息。