第 9 章: MIDI システムリソースへのアクセス


注:

バージョン 5.0 では、sound.properties ファイルを使用して、SequencerSynthesizerTransmitter および Receiver のデフォルトのデバイスを設定できます。詳細については、API の MidiSystem クラス、例については、このガイドの「付録 2: sound.properties ファイル」 を参照してください。


JavaTM Sound API は、サンプリングオーディオシステムを構成する場合と同様、柔軟性の高い MIDI システム構成用モデルを提供します。Java Sound API を実装することにより、さまざまな種類の MIDI デバイスの提供が可能になりました。さらに、サービスプロバイダの提供するほかの MIDI デバイスの追加およびインストールも可能です。コンピュータにインストールされる MIDI デバイスの種類をほとんど意識することなく、プログラムを作成できます。一方で、プログラムで MIDI システムのデフォルトを利用することも、利用可能な任意のデバイスをユーザが選択して使用することもできます。

ここでは、プログラムが、インストールされている MIDI リソースを認識し、使用する MIDI リソースにアクセスする方法を説明します。デバイスへのアクセスおよびオープンが完了すると、デバイス間の相互接続が可能になります。詳細は、次の章「MIDI メッセージの送信および受信」で説明します。

MidiSystem クラス

Java Sound API の MIDI パッケージにおける MidiSystem クラスの役割は、サンプリングオーディオパッケージにおける AudioSystem の役割に類似しています。MidiSystem は、インストールされた MIDI リソースにアクセスするための情報センターとして機能します。

MidiSystem への問い合わせを行なってインストールされているデバイスの種類がわかったら、利用可能なデバイスを繰り返し処理して、目的のデバイスへのアクセスを取得できます。たとえば、起動時に利用可能なシンセサイザを MidiSystem に問い合わせてそのリストを表示し、ユーザの選択を待つ、といった動作をするアプリケーションプログラムを作成できます。また、単にデフォルトのシンセサイザを使用するだけという、より単純なアプリケーションプログラムを作成することも可能です。

MidiSystem クラスは、また、MIDI ファイルと Sequence 間の変換を行うメソッドも提供します。具体的には、MIDI ファイルのファイル形式のレポート、およびほかのタイプのファイルの書き込みが可能です。

アプリケーションプログラムは、MidiSystem から次のリソースを取得できます。

この章では、最初の 4 つのリソースについて説明します。MidiSystem クラスのファイル処理機能については、第 11 章「MIDI シーケンスの再生、記録、および編集」および第 12 章「サウンドの合成」で説明します。MIDI システムがこれらのすべてのリソースにアクセスする方法については、このドキュメントの第 III 部「Service Provider インタフェース」を参照してください。

デフォルトデバイスの取得

Java Sound API を使用する通常の MIDI アプリケーションプログラムは、起動時に必要なデバイス群を取得します。デバイス群は、1 つまたは複数のシーケンサ、シンセサイザ、入力ポート、および出力ポートから構成されます。

デフォルトのシンセサイザデバイス、デフォルトのシーケンサデバイス、デフォルトの送信デバイス、およびデフォルトの受信デバイスが 1 つずつ存在します。通常、送信と受信の 2 つのデバイスは、それらがシステムで利用可能な場合、MIDI の入力ポートおよび出力ポートをそれぞれ表します。ここで、入力と出力の方向性を間違えやすいので注意してください。ポートの送信と受信は、物理ポートに接続する外部の物理デバイスとの関係ではなく、ソフトウェアとの関係で理解する必要があります。MIDI 入力ポートは、データを外部デバイスから Java Sound API Receiver に「送信」します。同様に、MIDI 出力ポートは、ソフトウェアオブジェクトからデータを「受信」して外部デバイスに中継します。

単純なアプリケーションプログラムは、インストールされているすべてのデバイスを調査せずに、デフォルトのデバイスを使用します。MidiSystem クラスには、デフォルトのリソースを検索する際に使用する、次のメソッドが含まれます。

    static Sequencer getSequencer()
static Synthesizer getSynthesizer()
static Receiver getReceiver()
static Transmitter getTransmitter()
	

最初の 2 つのメソッドは、システムのデフォルトのシーケンシングリソースおよび合成リソースを取得します。各リソースは、物理デバイスの場合もあれば、完全にソフトウェアに実装されている場合もあります。getReceiver メソッドは、送信された MIDI メッセージを受け取ってデフォルトの受信デバイスに中継する Receiver オブジェクトを取得します。同様に、getTransmitter メソッドは、デフォルトの送信デバイスに代わって MIDI メッセージを受信側に送信できる Transmitter オブジェクトを取得します。

インストールされているデバイスの確認方法

デフォルトのデバイスを使用する代わりに、システムにインストールされているすべてのデバイスの中から目的のデバイスを確実に選択するという方法もあります。アプリケーションプログラムでは、プログラムによって目的のデバイスを選択することも、利用可能なデバイスのリストを表示してユーザが選択できるようにすることも可能です。MidiSystem クラスでは、インストールされているデバイスを確認するためのメソッド、および指定された種類のデバイスを取得するための対応するメソッドが提供されます。

次に、インストールされたデバイスを確認する方法を示します。

    static MidiDevice.Info[] getMidiDeviceInfo()

このメソッドは情報オブジェクトの配列を返します。返される各 MidiDevice.Info オブジェクトは、シーケンサ、シンセサイザ、ポートをそれぞれ 1 種類、またはインストールされているほかのデバイスを示します。通常、システムにある特定の種類のインスタンスは、多くても 1 つです。たとえば、特定のベンダーの特定モデルのシンセサイザは、一度だけインストールされます。MidiDevice.Info には、デバイスを表す次の文字列が含まれます。

これらの文字列をユーザインタフェースに表示し、ユーザがデバイスリストから選択できるようにすることができます。

ただし、文字列をユーザに表示するためではなく、プログラムによってデバイスを選択するために文字列を使用する場合は、そのデバイスの情報をあらかじめ取得する必要があります。各デバイスを提供する企業は、このデバイス情報を文書に記載する必要があります。特定のデバイスの使用が必要なまたは推奨されるアプリケーションプログラムは、この情報を使ってデバイスを検出できます。この方法には、プログラムできるのは事前に情報のあるデバイス実装に限定されるという欠点があります。

このほかに、より一般的な方法として、複数の MidiDevice.Info オブジェクトを繰り返し処理して、各オブジェクトに対応するデバイスを取得し、各デバイスが使用に適しているかどうか、または少なくとも各デバイスがユーザに表示する選択リストに含めることが適切かどうかを、プログラムによって決定する方法です。次の節では、この方法を説明します。

目的のデバイスの取得

適切なデバイスの info オブジェクトが検出されると、アプリケーションプログラムは次の MidiSystem メソッドを呼び出して対応するデバイス自体を取得します。

    static MidiDevice getMidiDevice(MidiDevice.Info info)

このメソッドを使用できるのは、必要なデバイスが記述された info オブジェクトをすでに検出している場合です。ただし、getMidiDeviceInfo が返す info オブジェクトを解釈して必要なデバイスを判定できない場合、またはすべてのデバイスの情報をユーザに表示することを望まない場合は、代わりに、getMidiDeviceInfo が返すすべての MidiDevice.Info オブジェクトを繰り返し処理して、上記のメソッドを使って対応するデバイスを取得し、各デバイスが使用に適しているかどうかをテストする方法もあります。つまり、ユーザに表示するデバイスリストに含める前に、またはユーザを介在させずにプログラムによってデバイスを決定する手段の 1 つとして、各デバイスにそのクラスおよび機能を問い合わせることができます。たとえば、プログラムがシンセサイザを必要とする場合、次に示すように、インストールされている各デバイスを取得し、Synthesizer インタフェースを実装するクラスのインスタンスを判別してリストに表示し、ユーザの選択を待ちます。

// Obtain information about all the installed synthesizers.
Vector synthInfos;
MidiDevice device;
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
for (int i = 0; i < infos.length; i++) {
try {
device = MidiSystem.getMidiDevice(infos[i]);
} catch (MidiUnavailableException e) {
// Handle or throw exception...
    }
if (device instanceof Synthesizer) {
synthInfos.add(infos[i]);
    }
}
// Now, display strings from synthInfos list in GUI.	

別の例として、ユーザを介在させずに、プログラムによってデバイスを選択する方法について考えましょう。ほとんどの音色を同時に再生できるシンセサイザを取得するとします。 上記のように、すべての MidiDevice.Info オブジェクトを繰り返し処理して、デバイスがシンセサイザであることを確認できた時点で、SynthesizergetMaxPolyphony メソッドを呼び出して機能を問い合わせます。次の節で示すように、最大のポリフォニー (同時に演奏できる音) を保持するシンセサイザを予約します。ユーザにシンセサイザの選択を求めない場合でも、ユーザへの参考情報として、選択した MidiDevice.Info オブジェクトから返る文字列を表示することもできます。

デバイスのオープン

前の節では、インストールされているデバイスを取得する方法を示しました。ただし、デバイスはインストールされていても、利用できない場合があります。たとえば、別のアプリケーションプログラムが、排他的に使用している場合があります。 使用するプログラム用にデバイスを確実に予約するには、次のように MidiDeviceopen メソッドを使用する必要があります。

if (!(device.isOpen())) {
try {
device.open();
} catch (MidiUnavailableException e) {
// Handle or throw exception...
  }
}

デバイスにアクセスしてオープンすることにより予約が完了したら、そのデバイスをほかの 1 つまたは複数のデバイスに接続して、相互に MIDI データをやり取りすることができます。この手順は、第 10 章「MIDI メッセージの送信および受信」で説明します。

デバイスに関連する作業が完了したら、MidiDeviceclose メソッドを呼び出して、ほかのプログラムから利用できるようにデバイスを解放します。