[先頭の項目] [前の項目] [次の項目] [最後の項目]

第 3 章

オーディオシステムリソースへのアクセス

JavaTM Sound API では柔軟なシステム構成手法を採用しています。1 台のコンピュータにさまざまな種類のオーディオデバイス (ミキサー) をインストールできます。この API では、インストールされているデバイスの種類とその機能についての前提事項はほとんどありません。その代わりに、どのオーディオコンポーネントが利用可能であるか、およびそれらのコンポーネントにプログラムからアクセスする方法をシステムから通知させます。

この章では、どのようなサンプリングオーディオリソースがコンピュータにインストールされているかをプログラムで確認する方法、および利用可能なリソースへのアクセスを得る方法について説明します。この場合のリソースには、ミキサーおよび、ミキサーに所属する各種のラインも含まれます。

AudioSystem クラス

AudioSystem クラスは、組み込みサービスおよびサードパーティプロバイダが個別にインストールしたサービスを含む、オーディオコンポーネントの情報センターの役目をします。AudioSystem は、インストールされたサンプリングオーディオリソースにアプリケーションプログラムがアクセスするためのエントリポイントになります。AudioSystem に問い合わせて、どのようなリソースがインストールされているかを調べ、次にそれらのコンポーネントへのアクセスを取得できます。たとえば、特定の構成 (例: 前章のラインの説明で記した入出力構成のいずれか) を持つミキサーがあるかどうかを AudioSystem に問い合わせることからアプリケーションプログラムを始めることができます。次に、プログラムはミキサーからデータラインなどを取得できます。

アプリケーションプログラムが AudioSystem から取得できるリソースには次のようなものがあります。

情報オブジェクト

Java Sound API のクラスの中には、関連インタフェースについて有用な情報を提供するものがいくつかあります。たとえば、Mixer.Info は、インストールされているミキサーのベンダー、名前、説明、バージョンなどの詳細情報を提供します。Line.Info は特定のラインのクラスを取得します。Line.Info のサブクラスには Port.InfoDataLine.Info があり、Port.Info は特定のポート、DataLine.Info は特定のデータラインに関する詳細を取得します。これらのクラスの各々についてはこのあとで、それぞれの節で説明します。Info オブジェクトと、そのオブジェクトが記述するミキサーまたはラインオブジェクトを混同しないよう注意してください。

ミキサーの取得

通常、Java Sound API を使用するプログラムは最初の仕事の 1 つとして、ミキサー、またはミキサーのラインの少なくとも 1 本を取得します。それによりコンピュータの内外にサウンドを移動できます。使用するプログラムで特定の種類のミキサーが必要な場合や、利用可能なミキサーのリストを表示してユーザがミキサーを選択できるようにする場合があります。どちらの場合も、どのような種類のミキサーがインストールされているかを知る必要があります。AudioSystem には次のメソッドがあります。

    static Mixer.Info[] getMixerInfo()
このメソッドから返される Mixer.Info オブジェクトの各々は、インストールされているミキサーのタイプを示します。通常、1 つのシステムでは 1 つのタイプのミキサーが指定されている程度です。仮に複数タイプのミキサーが指定されていても、返された配列内にはそのタイプの Mixer.Info は 1 つしかありません。アプリケーションプログラムは、Mixer.Info オブジェクトの配列を反復して調べ、必要なミキサーを探します。Mixer.Info には、ミキサーの種類を示す次の文字列が含まれています。

これらは任意の文字列なので、特定のミキサーを必要とするアプリケーションプログラムは、予期すべき文字列と文字列の比較対象を知っていなければなりません。 ミキサーの製造元は、この情報を文書に記載すべきですが、 一般には特定のミキサーを必要としない場合が多く、この場合はアプリケーションプログラムはすべての Mixer.Info オブジェクトの文字列を表示して、ユーザにミキサーを選択させます。

適切なミキサーが見つかったら、アプリケーションプログラムは次の AudioSystem メソッドを呼び出して、目的のミキサーを取得します。

    static Mixer getMixer(Mixer.Info info)
プログラムが特定の機能を持つミキサーを必要とするが、特定のベンダーが製造したミキサーでなくてもよい場合があります。また、選択すべきミキサーをユーザが知っていることをあてにできない場合があります。このような場合は、Mixer.Info オブジェクト内の情報はあまり役に立ちません。その代わり、getMixerInfo から返されるすべての Mixer.Info オブジェクトを繰り返し実行し、getMixer を繰り返し呼び出すことによりミキサーを取得し、そのミキサーの機能を調べることができます。たとえば、ミキシング済みのオーディオデータを特定の本数のターゲットデータラインに同時に書き込むことのできるミキサーが必要だとします。この場合は、この Mixer メソッドを使って各々のミキサーに問い合わせを行います。

int getMaxLines(Line.Info info)

ここで、Line.InfoTargetDataLine を指定します。Line.Info クラスについては、次のセクションで説明します。

目的のタイプのラインを取得

ラインを取得する方法には次の 2 種類があります。

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 引数をとるものもありますが、引数を取らない形式を含むものもあります。

    Line.Info[] getSourceLineInfo()
    Line.Info[] getTargetLineInfo()

これらのメソッドは、特定のミキサーのすべての Line.Info オブジェクトの配列を返します。配列を取得したら、繰り返し実行して、MixergetLine メソッドを呼び出して各ラインを取得し、次に Lineopen メソッドを行って各々のラインをプログラムで使用できるよう予約します。

入出力ポートの選択

前節では目的のタイプのラインを取得する方法を説明しましたが、他のタイプのラインとポートについても同じことが当てはまります。Line.Info 引数を取る AudioSystem (または Mixer) メソッドであるgetSourceLineInfogetTargetLineInfoPort.Info オブジェクトを渡すことにより、すべてのソース (入力) ポートとターゲット (出力) ポートを取得できます。次に、返されたオブジェクト配列に対して Mixer の getLine メソッドを繰り返して、各ポートを取得します。

次に、Lineopen メソッドを呼び出して各々の Port を開きます。ポートを開くとは、そのポートをオンにすること、つまりポートを介したサウンドの往来を許可することを意味します。また、ポートを取得する前にいくつかのポートがすでに取得されている場合は、サウンドの移動に使用されるポートを閉じることができます。プラットフォームによってはデフォルトですべてのポートが解放されており、また、ユーザかシステム管理者が他のアプリケーションプログラムか OS のソフトウェアを使って特定のポートをオンまたはオフに設定している場合があります。

注意: ここで説明した方法でポートを開けば、特定のポートを選択して、そのポートに実際にサウンドが往来しているかどうかを確認することができます。しかし、これはユーザフレンドリーではない印象を与える場合があります。たとえば、同僚の迷惑にならないように、ユーザがスピーカのポートをオフにしているかもしれません。プログラムがユーザの意に反して突然音楽を鳴らし始めたら、気分を害することもありえます。別の例として、盗聴を防ぐために、ユーザが知らないときにコンピュータのマイクロフォンが絶対にオンにならない保証が欲しい場合があります。一般に、ユーザインタフェースによって表現されるようなユーザの意図に対して、プログラムが応答する場合以外は、プログラムでポートの開閉を行わないことを推奨します。ユーザまたは OS がすでに選択している設定を尊重してください。

必ずしも事前にポートの開閉を行わなくても、そのポートが取り付けられているミキサーは正しく機能します。たとえば、ミキサーのすべての出力ポートが閉じていても、サウンドの再生を開始してオーディオ出力ミキサーに送ることができます。データはミキサーに入り続け、再生は止まりません。ただし、ユーザには何も聞こえません。ユーザが出力ポートを開くと、その時点でポートから出るサウンドは聞こえる音になります。再生が及んだメディア内のどこからでも開始できます。

また、ミキサーに特定のポートがあるかどうかを知るためにポートをアクセスする必要はありません。たとえば、ミキサーが実際にオーディオ出力ミキサーかどうかを知るために、getTargetLineInfo を呼び出して、そのミキサーが出力ポートを持っているかどうかを調べることができます。設定 (開閉状態、ポートに備わっているコントロールの設定など) を変更したい場合を除き、ポート自体をアクセスする必要はありません。

オーディオリソースを使用するためのパーミッション

Java Sound API には、AudioPermission クラスがあります。そのサンプリングオーディオシステムに対してアプレット (またはセキュリティマネージャ付きで実行しているアプリケーションプログラム) が実行できるアクセスの種類を示します。録音のパーミッションは別々に制御されます。不正な盗聴などのセキュリティ上の危険を防ぐため、このパーミッションを与える際は注意すべきです。デフォルトでは、アプレットとアプリケーションは次のようにパーミッションを与えられます。

一般に、アプレットはセキュリティマネージャの監視のもとで実行されており、録音は許可されません。これに対し、アプリケーションはセキュリティマネージャの自動インストールは行わず、録音が可能です。ただし、アプリケーションに対してデフォルトのセキュリティマネージャが明示的に呼び出された場合は、アプリケーションは録音を許可されません。

アプレットとアプリケーションのどちらでも、録音のための明示的なパーミッションを与えられている場合は、セキュリティマネージャ付きで実行していても録音が可能です。

プログラムに録音 (または再生) のパーミッションが与えられていない場合は、ラインを開こうとすると例外がスローされます。パーミッションは API によって変更することができないので、この場合は、例外を受け取ってユーザに問題を報告する以外にプログラムでできることはありません。それ以外に何かを行っても、安全が保証されていないので無意味です。一般に、パーミッションは 1 つまたは複数のポリシー設定ファイルに設定されています。ユーザまたはシステム管理者はテキストエディタまたは Policy Tool プログラムを使ってこの設定ファイルを編集することができます。

セキュリティとパーミッションの詳細については、 http://java.sun.com/products/jdk/1.3/docs/guide/security の 「Security Architecture」 と 「Policy Permissions」、および Java Tutorial http://java.sun.com/docs/books/tutorial/ の 「Specialized Trails」 にあるセキュリティに関する項目を参照してください。



[先頭の項目] [前の項目] [次の項目] [最後の項目]

Copyright © 2000, Sun Microsystems Inc. All rights reserved.