注 -
|
JavaTM Sound API では柔軟なシステム構成手法を採用しています。 1 台のコンピュータにさまざまな種類のオーディオデバイス (ミキサー) をインストールできます。 この API では、インストールされているデバイスの種類とその機能についての前提事項はほとんどありません。 その代わりに、利用可能なオーディオコンポーネント、およびそれらのコンポーネントにプログラムからアクセスする方法をシステムから通知させます。
この章では、プログラムがコンピュータにインストールされているサンプリングオーディオリソースを確認する方法、および利用可能なリソースへのアクセスを得る方法について説明します。 この場合のリソースには、ミキサーおよびミキサーに所属する各種のラインが含まれます。
AudioSystem
クラスは、組み込みサービスおよびサードパーティプロバイダが個別にインストールしたサービスを含む、オーディオコンポーネントの情報センターの役目をします。 AudioSystem
は、インストールされたサンプリングオーディオリソースにアプリケーションプログラムがアクセスするためのエントリポイントになります。 AudioSystem
に問い合わせて、どのようなリソースがインストールされているかを調べ、次にそれらのコンポーネントへのアクセスを取得できます。 たとえば、アプリケーションプログラムはまず特定の構成 (前章のラインの説明で示した入出力構成など) を持つミキサーがあるかどうかを AudioSystem
に問い合わせることができます。 次に、プログラムはミキサーからデータラインなどを取得できます。
アプリケーションプログラムが AudioSystem
から取得できるリソースには次のようなものがあります。
一般に、システムには複数のミキサーがインストールされています。 通常は、オーディオ入力用のミキサーとオーディオ出力用のミキサーが、少なくとも 1 つずつあります。 また、ミキサーに I/O ポートがない場合もありますが、その場合はこれらはアプリケーションプログラムから音声を受け取り、ミキシングした音声をプログラムに返します。 AudioSystem
クラスにより、インストールされているすべてのミキサーのリストが提供されます。
各ラインはミキサーに関連付けられていますが、アプリケーションプログラムで明示的にミキサーを扱わなくても AudioSystem
から直接ラインを取得することができます。
アプリケーションプログラムは、形式変換を使ってオーディオデータの形式を別の形式に変換できます。 変換については第 7 章「ファイルコンバータおよび形式コンバータの使用」を参照してください。
AudioSystem
クラスは、オーディオファイルとオーディオストリーム間の変換を行うためのメソッドを提供します。 また、AudioSystem
クラスは、サウンドファイルのファイル形式を通知したり、別の形式でファイルを作成したりすることができます。 これらの機能については、第 7 章「ファイルコンバータおよび形式コンバータの使用」を参照してください。
Java Sound API のクラスの中には、関連インタフェースについて有用な情報を提供するものがあります。 たとえば、Mixer.Info
は、インストールされているミキサーのベンダー、名前、説明、バージョンなどの詳細情報を提供します。 Line.Info
は特定のラインのクラスを取得します。 Line.Info
のサブクラスには Port.Info
と DataLine.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
を繰り返し呼び出すことによりミキサーを取得し、そのミキサーの機能を調べることができます。 たとえば、ミキシング済みのオーディオデータを特定の本数のターゲットデータラインに同時に書き込むことのできるミキサーが必要だとします。 この場合は、この Mixer メソッドを使って各ミキサーに問い合わせを行います。
int
getMaxLines(Line.Info info)
ここで、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
メソッドを使用できます。
これらの各メソッドから返される配列内の各オブジェクトは、ラインの一意の種類を示しますが、必ずしもすべてのラインが示されるとは限りません。 たとえば、1 つのミキサーのラインのうちの 2 本または、異なるミキサーの 2 本のラインが同一のstatic Line.Info[] getSourceLineInfo(Line.Info info) static Line.Info[] getTargetLineInfo(Line.Info info)
Line.Info
オブジェクトを持つ場合は、その 2 本のラインは返された配列の中の 1 つの Line.Info
によって表されます。
Mixer
インタフェースには、すでに説明したソースラインとターゲットラインのためのさまざまな AudioSystem
のアクセスメソッドがあります。 これらの Mixer
メソッドには、AudioSystem
のメソッドと同様に Line.Info
引数を取るものもありますが、引数を取らない形式を含むものもあります。
これらのメソッドは、特定のミキサーのすべての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
をオープンします。 ポートのオープンとは、そのポートをオンにすること、つまりポートを介したサウンドの往来を許可することを意味します。 また、ポートを取得する前にいくつかのポートがすでに取得されている場合は、サウンドの移動に使用されるポートをクローズすることができます。 プラットフォームによってはデフォルトですべてのポートが解放されています。また、ユーザかシステム管理者がほかのアプリケーションプログラムまたは 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」にあるセキュリティに関する項目を参照してください。