7

誕生日にMIDIキーボードを買いました。MIDI 入力から信号を取得して音楽に変換するプログラム (MidiPiano) を見つけましたが、自分で書きたいと思います。

このようなタスクを実行するためのドキュメントはどこにありますか? MIDI プロトコルは十分に文書化されていますが、MIDI ポートは文書化されていません。

CodeProject の 2 つのプロジェクト (Project MIDI と C# MIDI Toolkit) を確認しましたが、目標に近づくことができずに何時間も費やしました。

プロジェクトへの参照は問題ありませんが、C# のみでお願いします。

4

6 に答える 6

7

http://msdn.microsoft.com/en-us/library/dd757277(VS.85).aspxにリストされているすべての必要な関数をラップする必要があります

短いメッセージを使用している場合はそれほど難しくありません。SysExまたは出力ストリーミングを実行する場合は、状況が少し複雑になります。

基本的な入力ポートに必要なのは、有効な入力ID(InputCount -1)を取得し、有効なIDを開いて入力を開始し、デリゲートを介してメッセージを受信することです...入力を停止して最後に閉じます。これは、これを実現する方法の非常に大まかな例です。ポートが閉じられて閉じられたコールバックが発生する前に、ポートが収集されないように注意する必要があります。そうしないと、システムがフリーズします。

幸運を!

名前空間MIDI
{{
    パブリッククラスInputPort
    {{
        private NativeMethods.MidiInProc midiInProc;
        プライベートIntPtrハンドル。

        public InputPort()
        {{
            midiInProc = new NativeMethods.MidiInProc(MidiProc);
            ハンドル=IntPtr.Zero;
        }

        public static int InputCount
        {{
            get {return NativeMethods.midiInGetNumDevs(); }
        }

        public bool Close()
        {{
            bool result = NativeMethods.midiInClose(handle)
                == NativeMethods.MMSYSERR_NOERROR;
            ハンドル=IntPtr.Zero;
            結果を返します。
        }

        public bool Open(int id)
        {{
            NativeMethods.midiInOpen(を返します
                アウトハンドル、
                id、
                midiInProc、
                IntPtr.Zero、
                NativeMethods.CALLBACK_FUNCTION)
                    == NativeMethods.MMSYSERR_NOERROR;
        }

        public bool Start()
        {{
            NativeMethods.midiInStart(handle)を返します
                == NativeMethods.MMSYSERR_NOERROR;
        }

        public bool Stop()
        {{
            NativeMethods.midiInStop(handle)を返します
                == NativeMethods.MMSYSERR_NOERROR;
        }

        private void MidiProc(IntPtr hMidiIn、
            int wMsg、
            IntPtr dwInstance、
            int dwParam1、
            int dwParam2)
        {{
            //ここでメッセージを受信します
        }
    }

    内部静的クラスNativeMethods
    {{
        internal const int MMSYSERR_NOERROR = 0;
        internal const int CALLBACK_FUNCTION = 0x00030000;

        内部デリゲートvoidMidiInProc(
            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(
            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);
    }
}
于 2010-01-02T21:00:49.693 に答える
2

私はちょうど c# midi 通信システムの開発中です。Sanford の midi ツールキットは優れていますが、レスリーの実装には多くの改善点があり、コードが読みにくくなっています。私のコードはできるだけシンプルです。必要に応じて、私に参加できます。数日以内に、完全に機能する midi モニターを公開します。http://puremidi.codeplex.com/を見てください。

于 2011-03-18T22:15:53.453 に答える
2

私もあまり見つけることができませんでしたが、Josh が言うように、Carl は間違いなく MIDI でかなりの仕事をしたので、彼に電子メールを送ってください.誰かが自分のものを C# に移植しましたか?

有望に見えた他の参考文献については...

純粋な C# ソリューションを探しているなら... Alvas.Audioを見てください。あなたが求めているものは少しハイエンドに見えますが、役立つかもしれません。

また多分プロジェクトミディ

于 2010-01-02T16:15:48.363 に答える
1

C#Midi Toolkitを使用して、キーボードからMIDI情報を受信します(オーディオカードのMIDI入力ポートに接続されています)。オーディオ(音楽またはトーン)を作成するには、デジタルオーディオデータの継続的なストリームを生成する必要があります。C#Synth Toolkit(midiツールキットと同じ作成者)から始めて、独自のシンセを作成することができます。

ただし、無料の(オープンソース)シーケンサープログラム(たとえばaudacity)をダウンロードし、VSTインストゥルメントプラグインを使用して作業を行うこともできます。Web上には無料のプラグインがたくさんあります。

于 2010-02-18T08:35:39.957 に答える
0

私は、MIDI キーボードでノートのオン/オフが発生するたびに UDP パケットを送信する Python スクリプトを作成することで、これを遠回しに解決しました。

C#/.NET を使用した Unity3D で MIDI over TCP/IP/UDP を受信

そうすれば、プラットフォーム固有の MIDI がラップされ、プラットフォームに依存しない C# コードを記述して UDP パケットを取得できます。

于 2014-02-21T11:49:51.293 に答える