Java Sound API の MIDI パッケージを利用するプログラムのほとんどが、サウンドを合成するために使用されます。MIDI ファイル、イベント、シーケンスおよびシーケンサの機能の詳細についてはほかの章で説明しましたが、それぞれの最終的な目標は音楽データをシンセサイザに送ってオーディオに変換することです。例外として、MIDI データをミュージシャンが読める楽譜に変換するプログラムや、ミキシングコンソールなどの外部の MIDI 制御デバイスにメッセージを送信するプログラムがあります。
したがって、Synthesizer
インタフェースが MIDI パッケージの基本となります。この章では、シンセサイザを操作してサウンドを再生する方法について説明します。多くのプログラムではシーケンサを使って MIDI ファイルデータをシンセサイザに送るだけなので、多くの Synthesizer
メソッドを直接呼び出す必要はありません。しかし、この章の最後の方で説明するように、シーケンサや MidiMessage
オブジェクトを使わずに直接シンセサイザを制御する方法があります。
MIDI 合成アーキテクチャーは、MIDI に不慣れな場合には複雑に感じられるものですが、要約すると、MIDI 合成の API には、次のインタフェースがあります。
また、次の 4 つのクラスがあります。 このすべての API を理解するために、次のセクションで MIDI 合成についての基本事項をいくつか挙げて、MIDI 合成と Java Sound API との関連性について説明します。第 8 章「MIDI パッケージの概要」の「Java Sound API での MIDI デバイス表現」の、「シンセサイザ」もあわせて参照してください。それ以降のセクションでは、API についてさらに詳しく説明します。シンセサイザは、どのようにして音を生成するのでしょうか。実装によって異なりますが、シンセサイザには、1 つまたは複数のサウンド合成技術が使用されています。たとえば、多くのシンセサイザでは Wavetable 合成を使用します。Wavetable シンセサイザはメモリーに保存されているオーディオ片を読み出して、さまざまなサンプリングレートで再生し、ループさせて、さまざまなピッチとデュレーションの音符を作り出します。たとえば、ノート C#4 (MIDI ノートナンバー 61) を奏でるサックスの音を合成するには、中央 C (MIDI ノートナンバー 60) のサックス演奏の録音から非常に短い断片を利用して、この断片を、録音時よりもわずかに速いサンプリングレートで繰り返すことにより、やや高いピッチのロングノートが作成されます。このほかに、保存されたオーディオを利用しないで、別のアルゴリズムを使ってオーディオをゼロから生成する周波数変調 (FM)、加算合成、物理モデリング方式を使うシンセサイザなどがあります。
すべての合成技術に共通することは、多くの種類のサウンドを合成できることです。異なるアルゴリズムを使ったり、同じアルゴリズム内でパラメータ設定を変えたりすることにより、さまざまなサウンド合成が可能になります。インストゥルメントは、特定の種類のサウンドを合成する場合に使用する仕様を表します。そのサウンドは、伝統的な楽器 (ピアノやバイオリンなど) をエミュレートすることもあれば、その他の種類の音源 (電話やヘリコプターの音など)、または実世界に存在しない音をエミュレートする場合もあります。General MIDI と呼ばれる仕様には 128 のインストゥルメントが標準として定義されていますが、ほとんどのシンセサイザではこれ以外のインストゥルメントの音も合成できます。多くのシンセサイザには、常時利用できる多数のインストゥルメントが組み込まれており、一部のシンセサイザには追加のインストゥルメントをロードするためのメカニズムもあります。
インストゥルメントはベンダー固有である場合があります。つまり、1 つのシンセサイザまたは同じベンダー製の複数のモデルのシンセサイザにのみ適用可能であるということです。この非互換性は、2 つの異なるシンセサイザで別のサウンド合成技術を使用する場合、または基本的な技術は同じでも内部アルゴリズムや内部パラメータが異なる場合に発生します。合成技術の細部は独自性が強いことが多いので、非互換性の問題はよく発生します。Java Sound API には、あるシンセサイザがあるインストゥルメントをサポートしているかどうかを調べる方法が用意されています。
インストゥルメントは、通常、プリセットされているものとみなすことができるため、そのインストゥルメントの音を作成するための合成技術の細部まで知る必要はありません。しかし、インストゥルメントの音をいろいろと変化させることはできます。ノートオンメッセージは、各ノートのピッチとボリュームを指定します。また、コントローラメッセージやシステム専用メッセージなど、ほかの MIDI コマンドを使ってサウンドを変更することもできます。
多くのシンセサイザは、同時に複数の異なるインストゥルメントのノートを再生できるという意味で、マルチティンバー (multimbral) またはポリティンバー (polytimbral) と呼ばれます。(音色 (timbre) とは、それにより聞き手が楽器の音をほかの楽器の音と区別できる、特徴的な音の性質のことです。マルチティンバーシンセサイザは、一度に 1 つのインストゥルメントだけではなく、実世界の楽器全体のアンサンブルをエミュレートできます。MIDI シンセサイザは通常、複数の異なる MIDI チャネルを利用することによりこの機能を実装しています。MIDI チャネルは、MIDI 仕様によりデータの送信が許可されているチャネルです。この場合、シンセサイザは実際は複数の音源ユニットの集合であり、各ユニットは異なるインストゥルメントをエミュレートし、別々の MIDI チャネルから受け取ったメッセージに個別に応答します。MIDI 仕様で提供されるチャネルの数は 16 なので、一般的な MIDI シンセサイザでは 16 種類までの異なるインストゥルメントを同時に演奏できます。シンセサイザは MIDI コマンド群のストリームを受け取ります。コマンド群の多くはチャネルコマンドです。(チャネルコマンドは、特定の MIDI チャネルを対象とするもの。詳細は、MIDI 仕様を参照。) シンセサイザがマルチティンバーの場合は、それぞれのチャネルコマンドを、コマンドに示されたチャネル番号に従って適正な音源ユニットに配送します。
Java Sound API では、これらの音源ユニットは、MidiChannel
インタフェースを実装するクラスのインスタンスです。synthesizer
オブジェクトには、少なくとも 1 つの MidiChannel
オブジェクトがあります。シンセサイザがマルチティンバーの場合は、このオブジェクトは複数 (通常は 16) です。それぞれの MidiChannel
は、別々の音源ユニットを表します。
シンセサイザの MidiChannel
オブジェクトには多少独自性があるため、すべてのチャネルに異なるインストゥルメントを割り当てる必要はありません。たとえば、16 台のピアノのアンサンブルのように、16 チャネルのすべてにピアノの音色を再生させても構いません。たとえば、チャネル 1、5、8 がギター、チャネル 2 と 3 がパーカッション、チャネル 12 がベースの音色を再生するというように、グループ分けすることも可能です。特定の MIDI チャネルで再生されているインストゥルメントを動的に変更することもできます。これは、プログラムチェンジ (program change) と呼ばれます。
ほとんどのシンセサイザでは、指定時間内にアクティブにできるインストゥルメントの数は 16 以下ですが、一般には、もっと多く提供されているインストゥルメントの中から選択して、必要に応じて特定のチャネルに割り当てることができます。
インストゥルメントはシンセサイザの中で階層的に編成されています。第 8 章MIDI パッケージの概要で説明したように、インストゥルメントはバンク番号とプログラム番号により配列されています。バンクとプログラムは、2 次元のインストゥルメントテーブルの行と列と考えることができます。バンクはプログラムの集合です。MIDI 仕様では、1 つのバンクに 128 までのプログラムを許可しており、128 までのバンクを許可しています。ただし、シンセサイザによっては、1 つだけまたは少数のバンクしかサポートしない場合や、1 つのバンクでサポートされるプログラムの数が 128 より少ない場合もあります。
Java Sound API では、その階層構造のにさらに上位のレベルがあります。それをサウンドバンクと呼びます。サウンドバンクには 128 までのバンクが収容でき、それぞれ 128 までのインストゥルメントが含まれます。サウンドバンク全体をメモリーにロードできるシンセサイザもあります。
現在のサウンドバンクからインストゥルメントを 1 つ選択するには、バンク番号とプログラム番号を指定します。MIDI 仕様では、これを 2 つの MIDI コマンド、bank-select と program-change を使って行います。Java Sound API では、バンク番号とプログラム番号の組み合わせは、Patch
オブジェクトにカプセル化されています。MIDI チャネルの現在のインストゥルメントを変更するには、新しいパッチを指定します。パッチは、現在のサウンドバンク内にあるインストゥルメントの 2 次元インデックスと考えることができます。
サウンドバンクもまた、数値によってインデックスが付けられていると思われるかもしれませんが、MIDI 仕様は、これに対応していません。Java Sound API では、Soundbank
オブジェクトはサウンドバンクファイルを読み込むことによって取得します。シンセサイザがサウンドバンクをサポートしている場合は、インストゥルメントをシンセサイザに必要に応じて個別にロードすることも、一度にすべてロードすることもできます。多くのシンセサイザにはデフォルトの組み込みサウンドバンクがあります。このサウンドバンクに含まれるインストゥルメントはシンセサイザからいつでも利用できます。
シンセサイザが同時に再生できる音色の数とノートの数を区別することは重要です。音色については、すでに「チャネル」で説明しました。同時に複数のノートを再生する能力をポリフォニーと呼びます。マルチティンバーでないシンセサイザでも、一般には複数のノート (すべてが同じ音色で、ピッチが異なる) を同時に演奏することができます。たとえば、G メジャー 3 や B マイナー 7 のようなコードを演奏するには、ポリフォニーが必要です。リアルタイムでサウンドを生成するシンセサイザには、同時に合成できるノートの数に制限があります。Java Sound API では、シンセサイザのこの制限は getMaxPolyphony
メソッドにより報告されます。
ボイス (voice) とは、単一のノートの連続したもので、たとえば、1 人で歌うことのできるメロディーなどです。ポリフォニーは、合唱団が歌う各パートのような複数のボイスで構成されます。たとえば 32 ボイスのシンセサイザは同時に 32 のノートを演奏できます。ただし、MIDI の文献の一部では、「ボイス」という用語は「インストゥルメント (instrument)」や「音色 (timbre)」と似た、これと別の意味で使用されています。
着信の MIDI ノートを特定のボイスに割り当てる処理は、ボイスアロケーションと呼ばれます。シンセサイザはボイスのリストを保持しており、どのボイスがアクティブ (現在出ている音がある) かを追跡します。ノートの音が鳴り止むと、ボイスはアクティブでなくなります。つまり、シンセサイザが受け取る要求で、次のノートを受け入れることができます。MIDI コマンド群の着信ストリームが、シンセサイザが生成できるよりも多くのノートを同時に要求することはよくあります。シンセサイザのすべてのボイスがアクティブなときは、次のノートオン要求をどのように処理すべきでしょうか。シンセサイザには、さまざまな技法を実装することができます。もっとも新しく要求されたノートを無視したり、もっとも古く開始されたノートなど、ほかのノートを中断することによって次のノートを演奏したりすることができます。
MIDI 仕様では要求されていませんが、シンセサイザは個々のボイスの内容を公開することができます。Java Sound API には、この目的のために VoiceStatus
クラスがあります。
VoiceStatus
は、ボイスの現在のアクティブ/非アクティブステータス、MIDI チャネル、バンク番号とプログラム番号、MIDI ノート番号、MIDI ボリュームを報告します。
次に、この背景知識をもとに Java Sound API の音の合成の仕様について考察します。
多くの場合、プログラムはほとんどの合成 API を明示的に呼び出すことなく、Synthesizer
オブジェクトを利用することができます。たとえば、標準の MIDI ファイルを再生する場合を考えます。ファイルを Sequence
オブジェクトにロードし、そのオブジェクトを再生するためにそのシーケンサからデータをデフォルトのシンセサイザに送信させます。シーケンス内のデータは随意にシンセサイザを制御し、正しい時期に正しいノートを再生します。
しかし、この簡単なシナリオでは不十分な場合もあります。シーケンスには正しい音楽が含まれているのにインストゥルメントが正しく再生されないことがあります。この状況は、MIDI ファイルの作成者の意図したインストゥルメントと現在シンセサイザにロードされているインストゥルメントが異なる場合に起こります。
MIDI 1.0 仕様は、bank-selsect コマンドと program-change コマンドについて規定しています。これらのコマンドは、各 MIDI チャネルで現在どのインストゥルメントを再生中であるかに関連します。ただし、この仕様では、各パッチ位置 (バンク番号とプログラム番号) にどのインストゥルメントを置くべきかについては定義していません。最新の General MIDI 仕様では、特定のインストゥルメントのサウンドに対応する 128 のプログラムを含むバンクを定義することにより、この問題に対処しています。General MIDI シンセサイザは、指定されたものと同種の 128 のインストゥルメントを使用します。仕様の内容が異なる General MIDI のシンセサイザの再生するサウンドは、同じインストゥルメントを再生しているつもりの場合でも、かなり異なることがあります。ただし、どの General MIDI シンセサイザでファイルを再生するかにかかわらず、MIDI ファイルの大部分について、まったく同じでなくても、類似した音が再生されなければなりません。
それにもかかわらず、すべての MIDI ファイル作成者が、General MIDI で定義された 128 の音色の制限内でファイルを作成しようとするわけではありません。ここでは、シンセサイザがデフォルトで持っているインストゥルメントのセットを変更する方法を説明します。シンセサイザにデフォルトがないということは、シンセサイザにアクセスしたときにインストゥルメントがロードされていないことを示すので、必ず最初にこの API を使います。
シンセサイザに現在、目的のインストゥルメントがロードされているかどうかを確認するには、次の Synthesizer
メソッドを呼び出します。
Instrument[] getLoadedInstruments()次に、返された配列を繰り返し調べ、現在ロードされているインストゥルメントを確認します。多くのアプリケーションでは、そのインストゥルメントの名前をユーザーインタフェースに表示して (
Instrument
の getName
メソッドを使用)、そのインストゥルメントを使用するかほかのインストゥルメントをロードするかどうかをユーザーに確認します。Instrument
API には、インストゥルメントが属しているサウンドバンクを報告するメソッドがあります。サウンドバンクの名前は、プログラムまたはユーザーがインストゥルメントの種類を確認するのに役に立ちます。
Soundbank getDefaultSoundbank()デフォルトのサウンドバンクが得られます。
Soundbank
API には、サウンドバンクの名前、ベンダー、バージョン番号を検索するためのメソッドがあり、これによりプログラムまたはユーザーはバンクを識別することができます。ただし、そのシンセサイザをはじめて使用するときは、デフォルトのサウンドバンクからシンセサイザにインストゥルメントがロードされていることを前提とすることはできません。たとえば、あるシンセサイザには多種多様な組み込みインストゥルメントが用意されていても、メモリーの制約により、自動的にはロードされない可能性もあります。
ユーザーの決定により、現在ロードされているものとは別のインストゥルメントをロードする場合があります (プログラムが決定する場合もあります)。次のメソッドを使って、シンセサイザに組み込まれている (サウンドバンクファイルからロードする必要のない) インストゥルメントを確認します。
Instrument[] getAvailableInstruments()これらのインストゥルメントをロードするには、次のメソッドを呼び出します。
boolean loadInstrument(Instrument instrument)このインストゥルメントがロードされるシンセサイザ内の位置は、そのインストゥルメントの
Patch
オブジェクト (Instrument
の getPatch
メソッドにより検索) で指定されます。
ほかのサウンドバンクからインストゥルメントをロードするには、まず、Synthesizer の
isSupportedSoundbank
メソッドを呼び出して、そのサウンドバンクがそのシンセサイザに対応するかどうかを確認します。対応しない場合は、システム内のほかのシンセサイザについて繰り返し調べ、そのサウンドバンクをサポートするものを探します。その後、次のどちらかのメソッドを呼び出して、サウンドバンクからインストゥルメントをロードします。
boolean loadAllInstruments(Soundbank soundbank) boolean loadInstruments(Soundbank soundbank, Patch[] patchList)名前が示すように、最初のメソッドは指定されたサウンドバンクからすべてのインストゥルメントをロードし、次のメソッドは指定されたインストゥルメントをサウンドバンクからロードします。また、
Soundbank の
getInstruments
メソッドを使ってすべてのインストゥルメントにアクセスしてから、loadInstrument
を使って 1 つずつインストゥルメントを選択してロードすることもできます。
ロードするインストゥルメントがすべて同じサウンドバンクに属する必要はありません。loadInstrument
または loadInstruments
を使って、あるサウンドバンクから特定のインストゥルメントの組をロードし、別のサウンドバンクから別のインストゥルメントの組をロードし、以下同様に別のバンクからもロードすることができます。
各インストゥルメントには、そのインストゥルメントをロードすべきシンセサイザ内の位置を指定する Patch
オブジェクトがあります。位置は、バンク番号とプログラム番号によって定義されます。位置を変更するためにパッチのバンク番号またはプログラム番号を変更する API はありません。
ただし、あるインストゥルメントを、パッチで指定された位置以外にロードすることは可能で、それには次の Synthesizer
メソッドを使用します。
boolean remapInstrument(Instrument from, Instrument to)このメソッドは、シンセサイザから第 1 引数のインストゥルメントをアンロードし、第 1 引数のインストゥルメントにより占められていたパッチ位置に第 2 引数のインストゥルメントをロードします。
あるプログラム位置にインストゥルメントをロードすると、その位置に先にロードされていたインストゥルメントは自動的にアンロードされます。新しいインストゥルメントに自動的に置き換えないで、明示的にインストゥルメントをアンロードすることもできます。Synthesizer
には、3 つのロードメソッドに対応する 3 つのアンロードメソッドがあります。シンセサイザがプログラムチェンジメッセージを受け取ったときに、そのメッセージが現在インストゥルメントがロードされていないプログラム位置を選択していた場合は、そのメッセージが送信された MIDI チャネルからはサウンドは再生されません。
一部のシンセサイザは、インストゥルメントに属するその他の情報をサウンドバンクに保存します。たとえば、Wavetable シンセサイザは、1 つまたは複数のインストゥルメントからアクセス可能なオーディオサンプルを保存します。サンプルは複数のインストゥルメントにより共有される場合があるので、どのインストゥルメントからも独立してサウンドバンクに保存されます。Soundbank
インタフェースと Instrument
クラスのどちらにも、getSoundbankResources
を呼び出すメソッドが提供されています。このメソッドにより、SoundbankResource
オブジェクトのリストが返されます。これらのオブジェクトの細部は、そのサウンドバンクが設計されているシンセサイザに固有に設定されます。Wavetable 合成では、リソースが、1 つの録音の断片から取得した一連のオーディオサンプルを含んだオブジェクトである場合があります。別の合成技術を使用するシンセサイザでは、種類の違うオブジェクトはシンセサイザの SoundbankResources
配列に保存される場合があります。
Synthesizer
インタフェースには、シンセサイザの機能に関する情報を返すメソッドがあります。
public long getLatency() public int getMaxPolyphony()待ち時間 (latency) は、MIDI メッセージがシンセサイザに配送される時間と、シンセサイザがそれに対応する結果を実際に作成する時間との間の最悪の場合の遅れを示します。たとえば、あるシンセサイザではノートオンイベントを受信してからオーディオを生成するまでに数ミリ秒を要します。
getMaxPolyphony
メソッドは、そのシンセサイザが同時に再生できるノートの数を示します。これについては、この章の「MIDI 合成について」の「ボイス」で説明しました。また、すでに説明したように、シンセサイザはボイスの情報を提供することができます。これを行うには、次のメソッドを使用します。
public VoiceStatus[] getVoiceStatus()返された配列内の各
VoiceStatus
は、ボイスの現在のアクティブ/非アクティブステータス、MIDI チャネル、バンク番号とプログラム番号、MIDI ノート番号、MIDI ボリュームを報告します。通常、配列の長さは getMaxPolyphony
により返される値と同じです。シンセサイザが演奏中でない場合は、すべての VoiceStatus
オブジェクトのアクティブステータスフィールドは、false
に設定されています。
シンセサイザの現在のステータスについて、MidiChannel
オブジェクトを検索してその状態を問い合わせて、ステータスについての付加情報を入手することができます。この機能については、次のセクションでさらに詳しく説明します。
シンセサイザの MidiChannel
オブジェクトに直接アクセスした方が便利な場合や、直接アクセスが必要になる場合があります。ここでは、そのような場合について説明します。
シーケンス (MIDI ファイルから読み取ったものなど) を使うときは、シンセサイザに MIDI コマンドを送る必要はありません。単にそのシーケンスをシーケンサにロードし、シーケンサをシンセサイザに接続して実行させるだけです。イベントのスケジューリングはシーケンサが処理し、その結果は予測できる音楽演奏となります。これは、欲しい音楽が事前にわかっていて、音楽をファイルから読み込む場合に適しています。
ただし、演奏の進行中に音楽が生成される場合もあります。たとえば、ユーザーインタフェースに音楽用のキーボードやギターのフレットボードが表示され、ユーザーがマウスをクリックして自由にノートを再生させる場合があります。また、アプリケーションが、音楽を演奏するためにではなく、ユーザーの動作に応答してサウンドエフェクトを生成するためにシンセサイザを使うことがあります。これは、ゲームで一般的に使われる方法です。また、アプリケーションがファイルから読み込んだ音楽を演奏しているときに、ユーザーがユーザーインタフェースから対話形式で動的にその音楽を変更できるようにする場合もあります。どの場合でも、MIDI メッセージは将来の決まった時点にスケジュールされるのではなく、ただちに配送される必要があるので、アプリケーションはシンセサイザに直接コマンドを送ります。
シーケンサを使わずにシンセサイザに MIDI メッセージを送る方法は、少なくとも 2 つあります。1 つは、MidiMessage
を構築し、Receiver
の send メソッドを使ってシンセサイザに渡す方法です。たとえば、中央 C (MIDI ノートナンバー 60) を MIDI チャネル 5 (one-based) にただちに生成するには、次のようにします。
ShortMessage myMsg = new ShortMessage(); // Play the note Middle C (60) moderately loud // (velocity = 93)on channel 4 (zero-based). myMsg.setMessage(ShortMessage.NOTE_ON, 4, 60, 93); Synthesizer synth = MidiSystem.getSynthesizer(); Receiver synthRcvr = synth.getReceiver(); synthRcvr.send(myMsg, -1); // -1 means no time stamp2 つ目は、message-passing 層 (
MidiMessage
と Receiver
API) を両方ともバイパスし、シンセサイザの MidiChannel
オブジェクトと直接対話する方法です。まず、次の Synthesizer
メソッドを使ってシンセサイザの MidiChannel
オブジェクトを検索します。
public MidiChannel[] getChannels()次に、目的の
MidiChannel
メソッドを直接呼び出します。これは、対応する MidiMessages
をシンセサイザの Receiver
に送って、シンセサイザ自体の MidiChannels
を使って通信を処理させるよりも、より直接的な方法です。たとえば、前の例に対応するコードは次のようになります。
Synthesizer synth = MidiSystem.getSynthesizer(); MidiChannel chan[] = synth.getChannels(); // Check for null; maybe not all 16 channels exist. if (chan[4] != null) { chan[4].noteOn(60, 93); }
MidiChannel
インタフェースには、MIDI 仕様で定められている「チャネルボイス」と「チャネルモード」メッセージに 1 対 1 で対応するメソッドがあります。noteOn メソッドの使用方法については、前述の例で説明しました。これらの標準メソッドのほかに、Java Sound API の MidiChannel
インタフェースには、対応するボイスまたはモードの "set" メソッドで設定された最新の値を検索する "get" メソッドが追加されています。
int getChannelPressure() int getController(int controller) boolean getMono() boolean getOmni() int getPitchBend() int getPolyPressure(int noteNumber) int getProgram()これらのメソッドはユーザーにチャネルの状態を表示したり、続いてチャネルに送る値を決める場合に利用できます。
MIDI 仕様では要求されていませんが、Java Sound API は、チャネルごとにソロとミュートの概念を追加します。これらの概念は、MIDI シーケンスのトラック上のミュートとソロに似ています。第 11 章「MIDI シーケンスの再生、記録、および編集」の「シーケンス内の個別のトラックのミュートまたはソロ機能」を参照してください。
ミュートがオンの場合は、このチャネルは無音となりますが、ほかのチャネルには影響しません。ソロがオンの場合は、このチャネルおよびソロがオンになっているほかのチャネルが演奏されますが (ミュートされている場合を除く)、ほかのチャネルは無音となります。ソロとミュートの両方がオンになっているチャネルは無音となります。MidiChannel
API には、次の 4 つのメソッドがあります。
boolean getMute() boolean getSolo() void setMute(boolean muteState) void setSolo(boolean soloState)
インストールされている MIDI シンセサイザにより生成されるオーディオは、一般にサンプリングオーディオシステムを介して配送されます。プログラムがオーディオ再生のアクセス権を持っていない場合は、シンセサイザのサウンドを聞くことはできません。この場合、セキュリティー例外がスローされます。オーディオのアクセス権の詳細は、第 3 章「オーディオシステムリソースへのアクセス」の「オーディオリソースを使用するためのアクセス権」を参照してください。