JavaTM 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) と呼ばれます。(音色 (ティンブル) とは、それにより聞き手が楽器の音を他の楽器の音と区別できる、特徴的な音の性質のことです。マルチティンブラルシンセサイザは、一度に 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 コマンド群の着信ストリームが、シンセサイザが生成できるよりも多くのノートを同時に要求することはよくあります。シンセサイザのすべてのボイスがアクティブなときは、次の Note On 要求をどのように処理すべきでしょうか。シンセサイザには、さまざまな技法を実装することができます。最も新しく要求されたノートを無視することや、他の、たとえば最も古く開始されたノートを中断するなどして、次のノートを演奏することができます。
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 には、そのインストゥルメントがどのサウンドバンクに属しているかをレポートするメソッドがあります。サウンドバンクの名前は、プログラムまたはユーザがインストゥルメントの種類を確認するのに役に立ちます。
次の Synthesizer
メソッドにより、デフォルトのサウンドバンクが得られます。
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
メソッドを使用します。
このメソッドは、シンセサイザから第 1 引数のインストゥルメントをアンロードし、第 1 引数のインストゥルメントにより占められていたパッチ位置に第 2 引数のインストゥルメントをロードします。boolean remapInstrument(Instrument from, Instrument to)
あるプログラム位置にインストゥルメントをロードすると、その位置に先にロードされていたインストゥルメントは自動的にアンロードされます。新しいインストゥルメントに置き換えずに、明示的にインストゥルメントをアンロードすることもできます。Synthesizer
には、3 つのロードメソッドに対応する 3 つのアンロードメソッドがあります。シンセサイザがプログラム変更メッセージを受け取ったときに、そのメッセージが現在インストゥルメントがロードされていないプログラム位置を選択していた場合は、そのメッセージが送信された MIDI チャネルからはサウンドは再生されません。
一部のシンセサイザは、インストゥルメントに属するその他の情報をサウンドバンクに保存します。たとえば、Wavetable シンセサイザは、1 つまたは複数のインストゥルメントからアクセス可能なオーディオサンプルを保存します。サンプルは複数のインストゥルメントにより共有される場合があるので、どのインストゥルメントからも独立してサウンドバンクに保存されます。Soundbank
インタフェースと Instrument
クラスのどちらにも、getSoundbankResources
を呼び出すメソッドが提供されています。このメソッドにより、SoundbankResource
オブジェクトのリストが返されます。これらのオブジェクトの細部は、そのサウンドバンクが設計されているシンセサイザに固有に設定されます。Wavetable 合成では、リソースが、1 つの録音の断片から取得した一連のオーディオサンプルを含んだオブジェクトである場合があります。別の合成技術を使用するシンセサイザでは、種類の違うオブジェクトはシンセサイザの SoundbankResources
配列に保存される場合があります。
Synthesizer
インタフェースには、シンセサイザの機能に関する情報を返すメソッドがあります。
待ち時間 (latency) は、MIDI メッセージがシンセサイザに配送される時刻と、シンセサイザがそれに対応する結果を実際に作成する時刻との間の最悪の場合の遅れを示します。たとえば、あるシンセサイザでは note-on イベントを受信してからオーディオを生成するまでに数ミリ秒を要します。public long getLatency() public int getMaxPolyphony()
getMaxPolyphony
メソッドは、そのシンセサイザが同時に再生できるノートの数を示します。これについては、この章の「MIDI 合成について」の「ボイス」で説明しました。また、すでに説明したように、シンセサイザはボイスの情報を提供することができます。これを行うには、次のメソッドを使用します。
返された配列内のpublic VoiceStatus[] getVoiceStatus()
VoiceStatus
はそれぞれ、ボイスの現在のアクティブ/非アクティブ状態、MIDI チャネル、バンク番号とプログラム番号、MIDI ノート番号、MIDI ボリュームをレポートします。通常、配列の長さは getMaxPolyphony
により返される値と同じです。シンセサイザが演奏中でない場合は、すべての VoiceStatus
オブジェクトのアクティブ状態フィールドは、false
に設定されています。
シンセサイザの現状ステータスについて、MidiChannel
オブジェクトを検索してその状態を問い合わせて、ステータスについての付加情報を入手することができます。この機能については、次のセクションでさらに詳しく説明します。
シンセサイザの MidiChannel
オブジェクトに直接アクセスした方が便利な場合や、直接アクセスが必要になる場合があります。ここでは、そのような場合について説明します。
シーケンス (MIDI ファイルから読み取ったものなど) を使うときは、シンセサイザに MIDI コマンドを送る必要はありません。単にそのシーケンスをシーケンサにロードし、シーケンサをシンセサイザに接続して実行させるだけです。イベントのスケジューリングはシーケンサが処理して、その結果は予測できる音楽演奏となります。音楽をファイルから読み込む場合で、欲しい音楽が事前に分かっていれば、このシナリオは適しています。
しかし、演奏の進行中に音楽が生成される場合もあります。たとえば、ユーザインタフェースに音楽用のキーボードやギターのフレットボードが表示され、ユーザがマウスをクリックして自由にノートを再生させる場合があります。また、アプリケーションが、音楽を演奏するためにではなく、ユーザの動作に応答してサウンドエフェクトを生成するためにシンセサイザを使うことがあります。このシナリオは、ゲームで一般的に使われる方法です。また、アプリケーションはファイルから読み込んだ音楽を演奏していて、ユーザインタフェースによりユーザがその音楽と対話して、動的にその音楽を変更できるようにする場合もあります。これらのどの場合でも、MIDI メッセージは将来の決まった時点にスケジュールされるのではなくてただちに配送される必要があるので、アプリケーションはシンセサイザに直接コマンドを送ります。
シーケンサを使わずに MIDI メッセージを送る方法は、少なくとも 2 つあります。1 つは、MidiMessage
を構築し、Receiver
のメソッドを使ってシンセサイザに渡す方法です。たとえば、中央 C (MIDI ノートナンバー 60) を MIDI チャネル 5 (one-based) にただちに生成するには、次のようにします。
2 番目の方法は、message-passing 層 (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 stamp
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()
Java Sound API は、チャネルごとにソロとミュートの概念を追加しています (MIDI 仕様では要求されていません)。これらの概念は、MIDI シーケンスのトラック上のミュートとソロに似ています。第 11 章「MIDI シーケンスの再生、記録、および編集」の「シーケンス内の個別のトラックのミュートまたはソロ機能」を参照してください。
ミュートがオンの場合は、このチャネルは無音となりますが、他のチャネルには影響しません。ソロがオンの場合は、このチャネルおよび、ソロがオンになっている他のチャネルが演奏されます (ミュートされていない場合) が、他のチャネルは無音となります。ソロとミュートの両方がオンになっているチャネルは無音となります。 MidiChannel
API には、次の 4 つのメソッドがあります。
boolean getMute() boolean getSolo() void setMute(boolean muteState) void setSolo(boolean soloState)
インストールされている MIDI シンセサイザにより生成されるオーディオは、一般的にサンプリングオーディオシステムを介して配送されます。プログラムがオーディオ再生のパーミッションを持っていない場合は、シンセサイザのサウンドを聞くことはできません。この場合、セキュリティ例外がスローされます。オーディオのパーミッションの詳細については、第 3 章「オーディオシステムリソースへのアクセス」の「オーディオリソースを使用するためのパーミッション」を参照してください。