VS2005からMIDIファイルを出力する方法
はてなで質問した通り、
■■■■■■■■■■■■■■■■■■
プログラム言語で、midiファイルを出力するための方法を教えて下さい。
優先順位:
C#>C++>C>VB>Java>その他の言語>prepmxを使う。>バイナリをごりごり書く。
私が書いたもので恐縮ですが、以下、参考になりませんか?
のMIDIDataライブラリ(LGPL)で出力できるようです(*試してません)
概要:
MIDIDataライブラリは、完全にフリーでオープンソースの、MIDIデータ作成・編集用ライブラリである。このライブラリは、MIDIデータの作成・ファイル入出力(SMFフォーマット0/1/2)、MIDIトラックの作成・追加・変更・削除、MIDIイベントの作成・追加・変更・削除など、 MIDIデータのあらゆる要素に迅速にアクセスする機能を提供している。
MIDIDataライブラリは普通のC言語で書かれているが、ソースのほか、ダイナミックリンクライブラリ(*.dll)の形で提供される。ゆえに、C/C++からはもちろんのこと、Visual BasicやDelphiから使用することもできる。最新のMIDIDataライブラリは、2007年現在おーぷんMIDIぷろじぇくとからダウンロードできる。
も参考になりそうです
■■■■■■■■■■■■■■■■■■
何らかのプログラム言語(特に.net framework)でMIDIを出力するための方法がほしかった。
プログラミングの本はほんとに、演奏はあるのだが、出力はなかったのである。
昔昔林晴比古のVisual C++ 6.0入門 シニア編にのってたなぁ。くらいである。
でも、MIDIを生成したかった。
id:kujirahand
さんの回答ではjavaによる方法。
すぐにできた。javaは正式に採用されているところがうれしいところ。
しかし、このjavadocという人は便利である。
C++やC#版のjavadocとかないのであろうか。A Hot Documentは、個人で買うには高すぎる。
Doxygenは設定が面倒。というかC#は正式にサポートしているのか?という不安がある。
で、C#で楽譜画像を読み込んで自動的に楽譜を認識してmidiに出力できたらいいなぁと思っていたので、
J#からやろうとするが、無理。J#はjavax.sound.midi.*;がないのである。
そこで、id:minesouta
さんのを採用することにする。
これはダウンロードしても、普通にVS2005で起動すると、設定ファイルがアップグレードされる。
で、ビルドはすぐに成功して、dllとlibが生成される。
なんだ大勝利ではないか。と思ったが泥沼にはまる。
これは、C#で読み込めないDLLだった。アンマネージコードがどうたら、という理由で、
DLLを参照しようとすると、アセンブリがどうのとか、comコンポーネントとかよくわからない単語が続いて
結局読み込めない。
ので、無理矢理 コンソールアプリケーションから、関数を呼び出す形で強引にする。
でも今度はエラーが130個くらいはいてくれる。
でも、そのほとんどは キャストできないエラーなので、
そこは手動で、キャストをしてあげる。
次のエラーは、min 関数が定義されていない。とか言われる。
これはどこを探してもmin関数が存在しないので、[もしかしたら.libファイルの中かも。]
多分minという名前なのだから、最小値を返せばいいのだと、無理矢理作ってしまえばOK。
こんな感じ。
long __stdcall min(long a, long b) {
if ( a > b ) {
return b;
} else {
return a;
}
}
a==bの時はどうなのだろうか。でもとりあえずこれで動いたのでOKとする。
次のエラーは、サンプルプログラムの
int _tmain(int argc, _TCHAR* argv[]) { MIDIData* pMIDIData = MIDIData_Create (MIDIDATA_FORMAT0, 1, MIDIDATA_TPQNBASE, 120); if (pMIDIData == NULL) { printf ("MIDIStatusオブジェクトの生成に失敗しました。\n"); return 0; } MIDITrack* pMIDITrack = MIDIData_GetFirstTrack (pMIDIData); /* 最初のトラックを取得 */ MIDITrack_InsertNote (pMIDITrack, 0, 0, 60, 100, 120); /* ドの音(Key=60 Vel=10)を挿入 */ / MIDITrack_InsertEndofTrack (pMIDITrack, 960); /* エンドオブトラックを挿入 */ MIDIData_Save (pMIDIData, "Test1.mid"); /* ファイルに保存 */ MIDIData_Save(pMIDIData, "Test1.mid"); /* ファイルに保存 */ MIDIData_Delete (pMIDIData); /* MIDIデータをメモリ上から削除 */ pMIDIData = NULL; return 0; }
の、MIDIData_Save(pMIDIData, "Test1.mid");
である。なんとこれが、存在しない。
ソースのどこを探しても存在しない。
これは困りまくって見たが、やはり状況は変わらないので、ソースを読むことにする。
MIDIData_Saveで検索すると、それに近いのが、結構いる。
MIDIData_SaveAsBinaryとか、MIDIData_SaveAsSMFとかいう人。
Binaryでやってみたら、だめだった。
でもMIDIData_SaveAsSMFの場合うまくいったので、
MIDIData_SaveAsSMF(pMIDIData, "Test1.mid");
とすればOK.
最後の関門は、どうやって音を出すの?である。
これは、どう考えてもMIDITrack_InsertNoteしかありえない。
でも、引数が意味不明。なのでここに記述しておく。
MIDITrack_InsertNote (pMIDITrack, 480, 0, 67, 50, 240); /* ソの音(Key=67 Vel=10)を挿入*/ /**つまり、 MIDITrack_InsertNote( pMIDITrack, 始まりの場所, MIDIチャネル, 音の高さ, ベロシティ, 音の長さ)ということか.*
ちなみに、始まりの場所とかのタイムラインは,四分音符一個分の長さが120である。、従って4/4の場合一小節で、480である。
今日はここまで。
このままでは無理なので、これを.net Frame Work上のC++からクラスライブラリを作成してから、
C#で読み込ませれば勝利できそう。
回答して下さった皆様ありがとうございました。
本当に感謝しております。