ノート
|
Java Sound APIでは柔軟なシステム構成手法を採用しています。 1台のコンピュータにさまざまな種類のオーディオ・デバイス(ミキサー)をインストールできます。 このAPIでは、インストールされているデバイスの種類とその機能についての前提事項はほとんどありません。 その代わりに、利用可能なオーディオ・コンポーネント、およびそれらのコンポーネントにプログラムからアクセスする方法をシステムから通知させます。
このセクションでは、プログラムがコンピュータにインストールされているサンプリング・オーディオ・リソースを確認する方法、および利用可能なリソースへのアクセスを得る方法を学習します。 この場合のリソースには、ミキサーおよびミキサーに所属する各種のラインが含まれます。
AudioSystemクラスは、組込みサービスおよびサード・パーティ・プロバイダが個別にインストールしたサービスを含む、オーディオ・コンポーネントの情報センターの役目をします。 AudioSystemは、インストールされたサンプリング・オーディオ・リソースにアプリケーション・プログラムがアクセスするためのエントリ・ポイントになります。 AudioSystemに問い合わせて、どのようなリソースがインストールされているかを調べ、次にそれらのコンポーネントへのアクセスを取得できます。 たとえば、アプリケーション・プログラムはまず特定の構成(前章のラインの説明で示した入出力構成など)を持つミキサーがあるかどうかをAudioSystemに問い合わせることができます。 次に、プログラムはミキサーからデータ・ラインなどを取得できます。
アプリケーション・プログラムがAudioSystemから取得できるリソースには次のようなものがあります。
AudioSystemクラスにより、インストールされているすべてのミキサーのリストが提供されます。 AudioSystemから直接ラインを取得することができます。AudioSystemクラスは、オーディオ・ファイルとオーディオ・ストリーム間の変換を行うためのメソッドを提供します。 また、サウンド・ファイルのファイル形式を通知したり、別の形式でファイルを作成したりすることができます。 これらの機能については、第7章「ファイル・コンバータおよび形式コンバータの使用」を参照してください。 Java Sound APIのクラスの中には、関連インタフェースについて有用な情報を提供するものがあります。 たとえば、Mixer.Infoは、インストールされているミキサーのベンダー、名前、説明、バージョンなどの詳細情報を提供します。 Line.Infoは特定のラインのクラスを取得します。 Line.InfoのサブクラスにはPort.InfoとDataLine.Infoがあり、それぞれ、特定のポートと特定のデータ・ラインに関する詳細を取得します。 これらの各クラスについては、このあとそれぞれのセクションで説明します。 Infoオブジェクトと、そのオブジェクトが記述するミキサーまたはライン・オブジェクトを混同しないよう注意してください。
通常、Java Sound APIを使用するプログラムは最初の仕事の1つとして、ミキサー、またはミキサーのラインの少なくとも1本を取得します。それによりコンピュータの内外にサウンドを入出力できます。 使用するプログラムで特定の種類のミキサーが必要な場合や、利用可能なミキサーのリストを表示してユーザーがミキサーを選択できるようにする場合があります。 どちらの場合も、インストールされているミキサーの種類を知る必要があります。 AudioSystemには次のメソッドがあります。
static Mixer.Info[] getMixerInfo()
このメソッドから返される各Mixer.Infoオブジェクトは、インストールされているミキサーの種類を示します。 通常、システムにある特定の種類のミキサーは、多くても1つです。 かりに数種類のミキサーが指定されていても、返された配列内にはその種類のMixer.Infoは1つしかありません。 アプリケーション・プログラムは、Mixer.Infoオブジェクトを繰返し処理し、必要なミキサーを探します。 Mixer.Infoには、ミキサーの種類を示す次の文字列が含まれています。
これらは任意の文字列なので、特定のミキサーを必要とするアプリケーション・プログラムは、予期すべき文字列と文字列の比較対象を知っていなければなりません。 ミキサーの製造元は、この情報を文書化すべきですが、 一般には特定のミキサーを必要としない場合が多く、その場合はアプリケーション・プログラムはすべてのMixer.Infoオブジェクトの文字列を表示し、ユーザーがミキサーを選択するようにします。
適切なミキサーが見つかったら、アプリケーション・プログラムは次のAudioSystemメソッドを呼び出して、目的のミキサーを取得します。
static Mixer getMixer(Mixer.Info info)
プログラムは特定の機能を持つミキサーを必要とするが、特定のベンダーが製造したミキサーでなくてもよい場合があります。 また、ユーザーが選択すべきミキサーを知らない可能性もあります。 このような場合は、Mixer.Infoオブジェクト内の情報はあまり役に立ちません。 そのかわり、getMixerInfoから返されるすべてのMixer.Infoオブジェクトに対して処理を反復し、getMixerを呼び出すことによりそれぞれのミキサーを取得し、各ミキサーの機能を調べることができます。 たとえば、ミキシング済みのオーディオ・データを特定の本数のターゲット・データ・ラインに同時に書き込むことのできるミキサーが必要だとします。 その場合は、int getMaxLines(Line.Info info)というMixerメソッドを使って各ミキサーに問合せを行います。
ここで、Line.InfoはTargetDataLineを指定します。 Line.Infoクラスについては、次のセクションで説明します。
AudioSystemオブジェクトからラインを直接取得するAudioSystemオブジェクトから取得したミキサーの中からラインを取得する(この章の「ミキサーの取得」を参照)ここでは、ミキサーをまだ取得しておらず、使用するプログラムが特定の種類のラインのみを必要とする単純なものであるとします。ミキサーの詳細情報は重要ではありません。 この場合は、AudioSystemメソッドを使用できます。
static Line getLine(Line.Info info)
これは、すでに説明したgetMixerメソッドと類似しています。 Mixer.Infoと異なり、引数として使用されるLine.Infoは目的のラインを指定するためのテキスト情報を持っていません。 その代わり、目的のラインのクラスに関する情報を持っています。
Line.Infoは抽象クラスなので、ラインを取得するには、そのサブクラスのどれか(Port.InfoまたはDataLine.Info)を使います。 次のコード(抜粋)では、DataLine.Infoサブクラスを使ってターゲット・データ・ラインを取得し、オープンします。
TargetDataLine line;
DataLine.Info info = new DataLine.Info(TargetDataLine.class,
format); // format is an AudioFormat object
if (!AudioSystem.isLineSupported(info)) {
// Handle the error.
}
// Obtain and open the line.
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException ex) {
// Handle the error.
//...
}
このコードでは、クラスとオーディオ形式以外の属性を指定しないでTargetDataLineオブジェクトを取得します。 ほかの種類のラインを取得する場合にも、これに類似したコードを使用できます。 SourceDataLineまたはClipの場合は、そのクラスをline変数のクラスとしてTargetDataLineの代わりに使用し、DataLine.Infoコンストラクタの最初の引数にもそのクラスを使用します。
Portの場合は、次のようなコードの中でPort.Infoのstaticインスタンスを使用できます。
if (AudioSystem.isLineSupported(Port.Info.MICROPHONE)) {
try {
line = (Port) AudioSystem.getLine(
Port.Info.MICROPHONE);
}
}
ミキサーが目的の種類のラインを持っているかどうかを知るためのisLineSupportedメソッドの使用法に注目してください。
すでに説明したように、ソース・ラインは、ミキサーが音声入力デバイスを表している場合はミキサーへの入力すなわちPortオブジェクトであり、ミキサーが音声出力デバイスを表している場合はSourceDataLineまたはClipオブジェクトです。 同様に、ターゲット・ラインはミキサーの出力です。つまり、オーディオ出力ミキサーの場合はPortオブジェクト、オーディオ入力ミキサーの場合はTargetDataLineオブジェクトです。 ミキサーが外部ハードウェア・デバイスにまったく接続されてない場合もあります。 たとえば、アプリケーション・プログラムから音声を受け取り、ミキシング済みの音声をそのプログラムに返送する内部ミキサーや完全なソフトウェア・ミキサーなどです。 この種のミキサーには、入力ラインの代わりにSourceDataLineまたはClipオブジェクトがあり、出力ラインの代わりにTargetDataLineオブジェクトがあります。
インストールされているミキサーでサポートされているソース・ラインとターゲット・ラインの種類を指定して詳細を調べるには、次のAudioSystemメソッドを使用できます。
static Line.Info[] getSourceLineInfo(Line.Info info)
static Line.Info[] getTargetLineInfo(Line.Info info)
これらの各メソッドから返される配列内の各オブジェクトは、ラインの一意の種類を示しますが、必ずしもすべてのラインが示されるとは限りません。 たとえば、1つのミキサーのラインのうちの2本または、異なるミキサーの2本のラインが同一のLine.Infoオブジェクトを持つ場合は、その2本のラインは返された配列の中の1つのLine.Infoによって表されます。
Mixerインタフェースには、すでに説明したソース・ラインとターゲット・ラインのための様々なAudioSystemのアクセス・メソッドがあります。 これらのMixerメソッドには、AudioSystemのメソッドと同様にLine.Info引数を取るものもありますが、 Mixerによっては、引数を取らない形式を含むものもあります。
これらのメソッドは、特定のミキサーのすべてのLine.Info[] getSourceLineInfo()Line.Info[] getTargetLineInfo()
Line.Infoオブジェクトの配列を返します。 配列を取得したら、繰返し処理して、Mixerの getLineメソッドを呼び出して各ラインを取得し、次にLineの openメソッドを行って各ラインをプログラムで使用できるよう予約します。
前のセクションでは目的の種類のラインを取得する方法を説明しましたが、ほかの種類のラインとポートについても同じことが当てはまります。 Line.Info引数を取るAudioSystem (またはMixer)メソッドであるgetSourceLineInfoとgetTargetLineInfoにPort.Infoオブジェクトを渡すことにより、すべてのソース(入力)ポートとターゲット(出力)ポートを取得できます。 次に、返されたオブジェクト配列を繰返し処理してMixerのgetLineメソッドを呼び出し、各ポートを取得します。
その後、Lineのopenメソッドを呼び出して各Portを開くことができます。 ポートを開くとは、そのポートをオンにすること、つまりポートを介したサウンドの往来を許可することを意味します。 また、ポートを取得する前にいくつかのポートがすでに開かれている場合は、サウンドの移動に使用しないポートをクローズすることができます。 プラットフォームによってはデフォルトですべてのポートがオンになっています。また、ユーザーかシステム管理者が他のアプリケーション・プログラムまたはオペレーティング・システムのソフトウェアを使って特定のポートをオンまたはオフに設定している場合があります。
警告: ここで説明した方法でポートをオープンすると、特定のポートを選択し、そのポートに実際にサウンドが往来しているかどうかを確認することができます。 ただし、これはユーザー・フレンドリではない印象を与える場合があります。 たとえば、同僚の迷惑にならないように、ユーザーがスピーカのポートをオフにしていることがあります。 ユーザーの意に反して突然音楽が鳴り響いたら、ユーザーはびっくりしてしまいます。 別の例として、盗聴を防ぐために、ユーザーの知らない間にコンピュータのマイクロフォンがオンにならないようにする場合があります。 一般に、ユーザー・インタフェースによって表現されるユーザーの意図に対してプログラムが応答する場合以外は、プログラムでポートのオープンやクローズを行わないようにすることをお薦めします。 ユーザーまたはオペレーティング・システムがすでに選択している設定を使用してください。
事前にポートのオープンやクローズを行わなくても、そのポートが取り付けられているミキサーは正しく機能します。 たとえば、ミキサーのすべての出力ポートがクローズしていても、サウンドの再生を開始してオーディオ出力ミキサーに送ることができます。 データはミキサーに流れ、再生はブロックされません。 ただし、ユーザーには何も聞こえません。 ユーザーが出力ポートを開くと、その時点でポートから出るサウンドが聞こえるようになります。メディア内の位置のどこからでも再生が開始できます。
また、ミキサーに特定のポートがあるかどうかを知るためにポートにアクセスする必要はありません。 たとえば、ミキサーが実際にオーディオ出力ミキサーかどうかを知るために、getTargetLineInfoを呼び出して、そのミキサーが出力ポートを持っているかどうかを調べることができます。 設定(オープンまたはクローズ状態、ポートに備わっているコントロールの設定など)を変更する場合を除き、ポート自体にアクセスする必要はありません。
Java Sound APIには、AudioPermissionクラスがあり、そのサンプリング・オーディオ・システムに対してアプレット(またはセキュリティ・マネージャ付きで実行しているアプリケーション)が持つことのできるアクセスの種類を示します。 録音のアクセス権は別々に制御されます。 不正な盗聴などのセキュリティ上の危険を防ぐため、アクセス権の許可は注意して行ってください。 デフォルトでは、アプレットとアプリケーションには次のようなアクセス権が付与されています。
アプレットもアプリケーションも、録音のための明示的なアクセス権が与えられている場合は、セキュリティ・マネージャ付きで実行していても録音が可能です。
プログラムに録音(または再生)のアクセス権が与えられていない場合は、ラインをオープンしようとすると例外がスローされます。 アクセス権はAPIによって変更できないので、この場合は、例外をキャッチしてユーザーに問題を報告する以外にプログラムでできることはありません。 (それ以外に何かを行っても、安全が保証されていないので無意味です。) 一般に、アクセス権は1つ以上のポリシー構成ファイルに設定されています。ユーザーまたはシステム管理者はテキスト・エディタやPolicy Toolプログラムを使ってこの構成ファイルを編集できます。
セキュリティとアクセス権の詳細は、「セキュリティ」ガイドの「セキュリティ・アーキテクチャ」と「ポリシーによるアクセス権」、および『Javaチュートリアル』の「Specialized Trails」にあるセキュリティに関する項目を参照してください。