第 1 章: Java Sound API の紹介


 

設計目標

JavaTM Sound API は、オーディオデータと Musical Instrument Digital Interface (MIDI) データの両方を含む音声メディアの入出力への効果と制御のための低レベル API です。Java Sound API は、拡張性と柔軟性を向上させるフレームワークによって、サウンド入出力に通常必要な機能に対する明示的な制御を提供します。

Java Sound API の対象者

サウンドはもっとも基本的な要素であるため、Java Sound API は広範なアプリケーション開発者のニーズに対応しています。Java Sound API は、たとえば次のような領域のアプリケーションに適用されます。

Java Sound API とほかのインタフェースの関係

Java Sound API は、Java プラットフォームでもっとも低レベルのサウンド機能を提供します。そして、アプリケーションプログラムにサウンド操作のための非常に多くの制御を提供するとともに、拡張性も備えています。Java Sound API は、システムリソース (オーディオミキサー、MIDI シンセサイザ、ほかのオーディオデバイスまたは MIDI デバイス、ファイルリーダおよびライター、サウンド形式コンバータなど) に対するインストール、アクセス、操作の各機能を備えています。Java Sound API には、高度なサウンドエディタやグラフィックツールはありませんが、それらのプログラムを作成するために使用できる機能を提供します。また、この API の備える低レベル制御機能は、一般的にエンドユーザが期待する以上のものです。

サウンド関連の要素を持つ Java プラットフォーム API はほかにもあります。Java Media Framework (JMF) はさらに高レベルの API で、現在は Java プラットフォームの標準拡張として入手可能です。JMF は、時間ベースメディアの取り込みと再生のための統合アーキテクチャ、メッセージ交換プロトコル、プログラミングインタフェースを定めています。基本的なメディア再生アプリケーションプログラムに、より簡単なソリューションを提供します。また、JMF を使用すると、オーディオとビデオ間など異種のメディア間の同期化が可能になります。一方、サウンドを重視するプログラム、特にバッファリングされたオーディオの再生を細かく制御する能力や MIDI シンセサイザを直接操作する能力など、高度な機能を必要とするプログラムでは、Java Sound API が役立ちます。サウンド機能に関連する Java API としては、このほかに、Java 3D および、電話と発話のための API があります。これらの API は、Java Sound API の実装を内部的に使用して実装できますが、使用しなくても構いません。

パッケージ

Java Sound API には、デジタルオーディオデータと MIDI データの両方をサポートする機能があります。これらの主な 2 つの機能のモジュールは、別々のパッケージで提供されます。

このほかに、次の 2 つのパッケージによって、サービスプロバイダ (アプリケーション開発者と対立する立場) が、Java Sound API の実装の機能を拡張するカスタムソフトウェアを作成できるようになります。

この章の後半では、サンプリングオーディオシステム、MIDI システム、SPI パッケージについて簡単に説明します。それぞれの詳細については、そのあと説明します。

サンプリングオーディオ

サンプリングオーディオとは

javax.sound.sampled パッケージが処理するデジタルオーディオデータを、Java Sound API では「サンプリングオーディオ」と呼びます。「サンプル」とは、信号の連続するスナップショットのことです。オーディオの場合、その信号は音波です。マイクロフォンがアコースティック信号をアナログの電気信号に変換し、そのアナログ信号を AD コンバータがサンプリングデジタル形式に変換します。次の図に、録音の一部を示します。

音波のサンプリング
音波のサンプリング

グラフの縦軸は音圧 (振幅) を示し、横軸は時間を示します。アナログ音波の振幅は一定の間隔で周期的に測定すると、デジタルオーディオ信号を構成する離散的なサンプル (図の赤いデータポイント) になります。中央の水平線は振幅 0 を示し、これより上の点は正の値のサンプル、これより下の点は負の値です。アナログ信号のデジタル近似の精度は、時間の分解能 (サンプリングレート) と 量子化つまり振幅の分解能 (各サンプルを表現するために使用するビットの数) に依存します。参考基準として、コンパクトディスク用に録音されるオーディオのサンプリングレートは 44,100 回/秒で、各サンプルのビット数は 16 です。

ここでは、「サンンプリングオーディオ」という用語はあまり厳密に定義していません。音波は、アナログ形式のまま離散間隔でサンプリングすることもできます。ただし、Java Sound API では、「サンプリングオーディオ」は「デジタルオーディオ」と同義です。

一般に、コンピュータ上のサンプリングオーディオは録音によって作成されますが、合成して生成する場合もあります (プッシュホン式電話の音声を作成する場合など)。「サンプリングオーディオ」という用語は、データの種類を表し、データの出所を表すものではありません。

デジタルオーディオデータの構造の詳細は、第 2 章「Sampled パッケージの概要」「書式付きオーディオデータとは」を参照してください。

オーディオ構成

Java Sound API は、特定のオーディオハードウェア構成を想定していません。システム上にさまざまな種類のオーディオコンポーネントをインストールできるように設計されており、それらには API を使ってアクセスできます。Java Sound API は、サウンドカードに対する入出力 (サウンドファイルの録音や再生など)、オーディオの複数のストリームのミキシングなど、一般的な機能をサポートしています。次に、一般的なオーディオアーキテクチャの例を示します。

以後の文章で、この図について説明しています。

一般的なオーディオアーキテクチャ

この例では、サウンドカードなどのデバイスにさまざまな入出力ポートがあり、ミキシングはソフトウェア内で行われます。ミキサーが受け取るデータは、ファイルから読み込んだもの、ネットワークからのストリーム、アプリケーションプログラムが進行中に生成したもの、MIDI シンセサイザが生成したものなどさまざまです。次に説明する javax.sound.midi パッケージは、シンセサイザのための Java 言語インタフェースです。ミキサーはすべてのオーディオ入力を 1 本のストリームにまとめるので、それを出力デバイスに送ってレンダリングすることができます。

MIDI

javax.sound.midi パッケージには、MIDI イベントの転送とシーケンシングのための API、およびそれらのイベントからのサウンドを合成するための API があります。

MIDI とは

サンプリングオーディオがサウンドそのものの直接表現であるのに対し、MIDI データは音、特に音楽を作成するためのレシピと考えることができます。MIDI データは、オーディオデータのようにサウンドを直接記述することはありません。代わりに、シンセサイザにより作成されるサウンドに影響を与えるイベントを記述します。MIDI データは、GUI (グラフィカルユーザインタフェース) のキーボードイベントとマウスイベントに類似しています。MIDI の場合は、イベントは鍵盤に対するアクション、または楽器のペダル、スライダ、スイッチ、つまみなどに対するアクションであると考えることができます。これらのイベントは、実際にハードウェアとしての楽器で作られたものである必要はありません。ソフトウェアでシミュレーションしたものを MIDI ファイルに保存することができます。これらのファイルを作成、編集、実行するプログラムをシーケンサと呼びます。コンピュータ用サウンドカードには MIDI 制御可能な音楽シンセサイザチップが搭載されていることが多く、シーケンサから MIDI イベントを送ることができます。シーケンサは、完全にソフトウェア内に実装することもできます。シンセサイザは、受け取った MIDI イベントを解釈してオーディオ出力を生成します。通常、MIDI データから合成される音は、発話などではなく、音楽です。MIDI シンセサイザにより、各種のサウンドエフェクトを生成することもできます。

一部のサウンドカードには MIDI 入出力ポートがあり、外部ハードウェアデバイス (キーボードシンセサイザなどの機器) を接続できます。アプリケーションプログラムは、外部の MIDI 搭載楽器が生成したイベントを MIDI 入力ポートから受信できます。プログラムは、コンピュータの内部シンセサイザを使って音楽の演奏をしたり、MIDI ファイルとしてディスクに保存したり、音符に変換したりすることができます。また、プログラムは MIDI 出力ポートを使って外部の楽器を演奏したり、録音機器などの外部デバイスを制御することができます。

MIDI データについては、第 8 章「MIDI パッケージの概要」に説明がありますが、特に「MIDI について: ワイヤおよびファイル」の節に詳細な説明がありますので参照してください。

MIDI の構成

下の図に、Java Sound API を基にした、MIDI 構成例の中の主なコンポーネント間の機能の関係を示します。オーディオの場合と同様に、Java Sound API ではさまざまな MIDI ソフトウェアデバイスをインストールして相互接続することができます。ここで示すシステムは、一例に過ぎません。コンポーネント間のデータの流れは、矢印で示してあります。データは、標準ファイル形式のデータの場合もあり、オーディオ、raw MIDI バイト、時刻のタグが付いた MIDI メッセージなどの場合もあります (図の右下隅の key を参照)。

以後の文章で、この図について説明しています。

MIDI 構成の例

この例では、アプリケーションプログラムは、ディスク上に標準 MIDI ファイルとして保存されている楽譜をロードして音楽の演奏の準備をします (図の左側)。標準 MIDI ファイルには、トラックが含まれています。それぞれのトラックは、時刻のタグが付いた MIDI イベントのリストです。イベントのほとんどは音符 (ピッチとリズム) を表します。この MIDI ファイルをソフトウェアシーケンサが読み込み、次に「演奏」します。シーケンサは、内部または外部のシンセサイザなどのデバイスに MIDI イベントを送信することによって音楽の演奏を行います。シンセサイザ自体が、特定の楽器のサウンドをエミュレートするための指示が含まれているサウンドバンクファイルを読み込むこともあります。それ以外の場合は、シンセサイザはすでにシンセサイザにロードされている楽器のサウンドをすべて使って、MIDI ファイルの中の音を再生します。

図に示すとおり、MIDI イベントは MIDI 出力ポートを使って外部のシンセサイザに送信する前に、時刻のタグが付いていない raw MIDI に変換される必要があります。同様に、外部 MIDI ソース (図の鍵盤楽器) からコンピュータに入力される raw MIDI データは時刻のタグが付いた MIDI メッセージに変換されます。このメッセージによりシンセサイザを制御できます。また、あとで使用するためにシーケンサがこのメッセージを保存しておくことができます。MIDI データの流れに関しては、MIDI について説明している章に詳細があります (第Ⅱ部を参照)。

サービスプロバイダインタフェース

javax.sound.sampled.spi パッケージと javax.sound.midi.spi パッケージには、ソフトウェア開発者がオーディオまたは MIDI リソースを新規に作成するために使用できる API が含まれています。これらのリソースは、ユーザに個別に配布したり、既存の Java Sound API 実装に「プラグイン」させることができます。この方法で追加できるサービス (リソース) として、次のようなものがあります。

場合によっては、サービスが、サウンドカードなどのハードウェアデバイス機能へのソフトウェアインタフェースになります。その場合、サービスプロバイダは、ハードウェアのベンダーと同じ意味になります。また、純粋にソフトウェア内にあるサービスもあります。たとえば、シンセサイザやミキサーがサウンドカード上のチップへのインタフェースになる場合や、ハードウェアをまったくサポートしないで実装されている場合などです。

Java Sound API の実装にはサービスの基本セットが含まれていますが、サービスプロバイダインタフェース (SPI) パッケージを使ってサードパーティによる新しいサービスの作成も可能です。このようなサードパーティサービスは、組み込みサービスと同様の方法でシステムに統合されます。sampled パッケージ内の AudioSystem クラスと midi パッケージ内の MidiSystem クラスは、アプリケーションプログラムがサービスに明示的または暗黙的にアクセスするための調整役として働きます。あるサービスの存在が、そのサービスを使用するアプリケーションプログラムには見えないこともよくあります。サービスプロバイダ機構により、Java Sound API をベースとするアプリケーションプログラムのユーザは、便利さを享受することができます。それは、Java SDK または実行環境の新しいリリース、また多くの場合、アプリケーションプログラムそのものの新しいリリースさえも必要とせずに、プログラムに新しいサウンド機能を追加することができるからです。