研究テーマ->音楽ソフトの開発->準備  
  MIDIを扱うソフトの開発について紹介します。  
SMF編集エンジン
最終出力が、SMF(MIDIファイルのこと)であれば、SMFの読み込み、書き出し、再生、編集の機能をもつクラスを用意することが必要になります。これを行うのに、MIDIやSMFについての知識が必要になりますが、私は「MIDIバイブル I」「MIDIバイブル II」という本を使用しています。これに必要なことは、ほとんど書いてありますので、他の本は必要ありません。また、すでにプログラムを作ってしまったあとに発行された本なので、私はあまり使っていないのですが、これからプログラムを作ろうとする人であれば、「Windowsサウンドプログラミング」という本も参考になると思います。その他、役に立ちそうな本は、こちらに載せています。
イベントの管理
MIDIを扱うクラスをどのように設計するかですが、幾つかの選択肢があります。MIDIの最小単位は、メッセージです。メッセージとは、音を鳴らせ、音を止めろ、音色を変えろなどの命令のことと考えると分かりやすいと思います。これらは、MIDIの規格では、ノートオンメッセージ、ノートオフメッセージ、プログラムチェンジなどの言葉で定義されています。これがSMFのファイルになると、時間の情報が加わり、ノートオンイベント、ノートオフイベント、プログラムチェンジイベントなどの、イベントが最少単位になります。
SMFはこれらのイベントの集まりでできていますから、イベントをどのような仕組で管理するかが重要になります。メッセージやイベントに、どのような種類のものがあるかは、こちらをご覧ください。
ポイント
SMFはイベントの集まり
イベントは、厳密には、ノートオンメッセージ、ノートオフメッセージ、プログラムチェンジなど、イベントごとに、内部に保持するデータが異なりますが、共通点も多いですから、これらを同じデータ型にあてこんで、管理するのが楽です。すべて同じ型にあてこんだイベントの集合体を管理する方法には、2つの選択肢があります。1つは、配列を使用する方法、もう1つは、リスト構造を使用する方法です。
配列の場合、イメージ的に頭で理解しやすく、操作は配列間のメモリのコピーでほとんど済んでしまうのですが、あらかじめ、ファイルに含まれるイベントの総数が幾つになるかを把握することはできませんから、余分にメモリを確保しておくことになります。
リスト構造は、前のイベントへのポインタと次のイベントのポインタを保持することで、イベントの連鎖をリストとして管理します。こちらの場合は、事前にイベントの総数が分かっていなくても問題ありません。ただし、リスト構造に対して、イベントの追加、削除などを行う処理を作成する必要があります。私の場合は、当初、配列構造でプログラムを書いていましたが、現在は、それをリスト構造に変更することを考えています。
ポイント
イベントの管理はリスト構造のほうが良い
データ形式に関する配慮
シーケンスソフトでSMFを開くと、入力されたノート(音符)は、発音タイミング、ノートナンバー、ベロシティ、ゲートタイムの4つの情報を持っていることが分かります。発音タイミングは、たとえば、1小節目の2拍目の240チックというような感じのデータが入っています。ノートナンバーは、60とかの音高を示す数字で、C4のように音名とオクターブで表示されている場合もあります。ベロシティは音の強さです。ゲートタイムは、音が発音されてから止まるまでの長さです。
シーケンスソフトでは、1つ1つの音は上記のようなデータで管理、表示されますが、実際のSMFには、全く異なる形式でデータが保持されています。SMFでは、ノートイベントというものはなく、代わりに、ノートオンイベント、ノートオフイベントがあります。シーケンスソフトでは、この2つをひとまとめにして、ゲートタイムをノートオンイベントとノートオフイベントの間隔から計算して表示しているのです。
シーケンスソフトのような形式でデータをもつことをQ1形式、SMFのような形式でデータをもつことをQ2形式と言います。SMF内のイベントを編集する処理を作成する場合は、Q2の形式でデータを持っているほうが色々と楽なことが多いです。ただし、最終的にはQ1の形式で出力しなければなりませんから、Q1とQ2の両方の形式を定義し、それらを行き来できるような処理を用意しておくことが必要になります。
ポイント
ノートオンイベントとノートオフイベントではなく、ノートイベントとして管理したほうが処理が楽
時間データに関する配慮
シーケンスソフトでは、イベントのタイミングは、1小節目の2拍目の240チックというように、曲の先頭位置からの時間間隔で表示されます。SMF内で時間データを保持しているのは、デルタタイムと呼ばれるデータですが、これは、曲の先頭位置からの時間間隔ではなく、前のイベントからの時間間隔を保持しています。(このデータは可変長データとして保持されます。)SMFを扱うクラス内で、時間データを絶対時間でもつのか、相対時間でもつのかは、よく検討する必要があります。相互に行き来できるようにしておくとプログラミングが楽になります。
移植に備えて基底クラスを作成する
MIDIデータと似た構造のものに、携帯用の着メロファイルのデータがあります。DoCoMoと、SoftBank, auでは着メロファイルの構造が少し異なっていますが、基本的にはSMF(MIDIファイル)を元にできています。
たとえば、着メロファイルも、プログラムチェンジやノートイベントなどの、イベントの集合体と考えられますが、1つ1つの音はQ2形式のノートイベントとして保持されています。また、SMFでは、イベントを含むデータの一塊を、チャンクという概念で管理しています。つまり、SMFにはいくつかのチャンクが含まれており、最小単位であるイベントは、トラックチャンクなど、何れかのチャンクに含まれる形になっています。この構造は、着メロファイルでも基本的に同じです。
上記のことから、MIDI、各社の着メロに共通する部分を基底クラスとして作成しておき、MIDIを扱うクラスや着メロを扱うクラスを派生させておく形で開発しておけば、SMF編集エンジンから着メロ編集エンジンへの移植が楽になることが分かると思います。ただし、前提として、着メロファイルのフォーマットが分かっている必要がありますが、このフォーマットはSMFのフォーマットのように一般には公開されていません。