c# - 从 C# 中的 MIDI 端口获取信号

标签 c# midi

我为生日买了一个 MIDI 键盘。我找到了一个程序 (MidiPiano),它从 MIDI 输入获取信号并将其转化为音乐,但我更想自己编写一个。

在哪里可以找到执行此类任务的文档? MIDI 协议(protocol)有详细记录,但 MIDI 端口没有。

我检查了 CodeProject 的两个项目(Project MIDI 和 C# MIDI Toolkit),但花了很多时间都没有接近我的目标。

对项目的引用是可以的,但请仅使用 C#。

最佳答案

您需要包装在 http://msdn.microsoft.com/en-us/library/dd757277(VS.85).aspx 中列出的所有需要​​的函数

如果你只是使用短消息,这并不太难,如果你想做 SysEx 或输出流,事情会变得有点复杂。

基本输入端口所需要做的就是获取有效的输入 ID (InputCount -1),将有效的 ID 传递给 Open,开始输入,通过委托(delegate)接收消息...停止输入,然后最后关闭它。这是如何实现这一点的一个非常粗略的示例 - 您将需要进行一些检查,并注意在端口关闭和关闭回调发生之前不会收集端口,否则您将卡住您的系统!

祝你好运!

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);
    }
}

关于c# - 从 C# 中的 MIDI 端口获取信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1991159/

相关文章:

ios - 在 iOS 上使用 midi 演奏打击乐器

Java声音生成产生嘈杂的声音

c# - 为什么我应该为具体的 DataProvider 类创建接口(interface)

c# - 路径中的非法字符

c# - WPF 应用程序将数据表写入 Excel 的更有效方法?

audio - 如何在VirtualBox Windows 98中播放Midi音乐?

笔记本电脑退出 hibernate 后,Java MIDI 音频出现延迟

c - USB MIDI协议(protocol)理解

c# - 按父项和子项排列的订单列表

c# - 任何方法到 "Safely"调用 assembly.GetTypes()?