> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SHAPE の概要

> XBOX One SHAPE オーディオ ハードウェアが固定機能ブロック、ミックス バッファー、DMA を使用して XMA、SRC、フィルタリングのフローグラフを高速化する方法。

XBOX One オーディオ システムの主要コンポーネントである Scalable Hardware Audio Processing Engine (SHAPE) は、次の機能を実行します。

* 固定機能のハードウェア ブロック (XMA、Sample Rate Convertor (SRC)、イコライザーおよびコンプレッション、フィルター ボリューム) を使用して、一般的に使用されるオーディオ機能を効率的に実行します
* これらのブロックを制御するために、プログラム可能な組み込みの Audio Control Processor (ACP) を提供します

以下は、高速動作、およびメイン メモリ バスのトラフィックを最小限に抑えるために利用可能です。

* システム メモリにアクセスするための Direct Memory Access (DMA) プロセス
* *ミックス バッファー*と呼ばれる特別な内部メモリ

  ミックス バッファーは、オーディオ フレーム 1 つ分のデータを格納するメモリ ブロックです。SHAPE ハードウェアは通常、1 つまたは 2 つのミックス バッファーから読み取り、出力ミックス バッファーに書き込みます。XMA デコード、DMA、SRC ブロックなど、この一般的なプロセスにはいくつかの例外があります。

多くのタイトルはフローグラフを直接実装しません。`XAudio2` およびオーディオ ミドルウェアは、SHAPE コンポーネントを暗黙的に実装します。ただし、フローグラフを構築することで、XBOX One コンソールのオーディオ アクセラレーション機能に対する最大の柔軟性とアクセスが提供されます。

このトピックでは、SHAPE ハードウェアと機能ブロックの概要について説明します。

* [制御フロー](#ID4EAB)
* [DMA](#ID4EWC)
* [XMA](#ID4EYD)
* [PCM](#ID4EFE)
* [Sample Rate Convertor (SRC) ブロック](#ID4EOE)
* [イコライゼーションとコンプレッション](#ID4ECF)
* [フィルター/ボリューム ブロック (FLTVOL)](#ID4EBH)
* [ミックス バッファー](#ID4EYH)
* [オーバーフロー、マグニチュード、飽和](#ID4ELAAC)
* [SHAPE キュー](#ID4EDDAC)
* [プログラミングに関する考慮事項](#ID4EMDAC)

<a id="ID4EAB" />

## 制御フロー

オーディオ処理の一般的な制御フローを以下に示します。

1. 圧縮された XMA オーディオ データ ファイルがメイン システム メモリに読み込まれます。

2. XMA デコーダー ブロックが XMA データの一部を Pulse Code Modulation (PCM) データにデコードします。これは、システム メモリ内の XMA デコード バッファーに出力を保存します。

3. SRC ブロックが XMA デコード バッファーから PCM サンプルを読み取り、必要なサンプル レート変換とピッチ シフトを実行します。これにより、任意のサンプリング レートのオーディオ データを SHAPE アクセラレーター ブロックに取り込むことができます。SRC ブロックは、48 kHz の固定レートで実行されるオーディオ データを内部ミックス バッファーに出力します。

4. その後、追加の SHAPE 処理と、一時ミックス バッファーへの読み書きが実行されます。処理は ACP によって制御され、ACP 自体は、このドキュメント セットに記載されている ACP API を通じてアプリケーションによって駆動されます。処理には、イコライゼーション、コンプレッション、フィルター スケーリング、およびボリューム スケーリングが含まれます。

5. 最終ステージは *Speaker Output Accumulation* と呼ばれ、スピーカー ミックス バッファーが複数のサウンド ソースからのサンプルを収集およびミックスして再生します。このステージでは、オプションのグローバル オーディオ エフェクトを処理できます。

メイン アプリケーション CPU で任意の処理を実行するには、代替プロセスを使用できます。最初の 3 つのステップは、前述のものと同一です。

1. 圧縮された XMA オーディオ データ ファイルがメイン システム メモリに読み込まれます。

2. XMA デコーダー ブロックが XMA データの一部を PCM データにデコードし、システム メモリ内の XMA デコード バッファーに出力を保存します。

3. SRC ブロックが XMA デコード バッファーから PCM サンプルを読み取り、必要なサンプル レート変換とピッチ シフトを実行します。これにより、任意のサンプリング レートのオーディオ データを SHAPE アクセラレーター ブロックに取り込むことができます。SRC ブロックは、48 kHz の固定レートで実行されるオーディオ データを内部ミックス バッファーに出力します。

4. このステップで、プロセス フローが分岐します。DMA システムを使用して、1 つ以上のミックス バッファーをメイン システム メモリに転送します。

5. アプリケーション CPU がメイン メモリ内のバッファーに対して必要な信号処理を実行します。

6. DMA システムを使用して、処理済みのオーディオ データをメイン メモリ バッファーから一時ミックス バッファーに転送します。このステップの後、プロセスは前述のものと同一です。

7. その後、追加の SHAPE 処理と、一時ミックス バッファーへの読み書きが実行されます。処理は ACP によって制御され、ACP 自体は、このドキュメント セットに記載されている ACP API を通じてアプリケーションによって駆動されます。処理には、イコライゼーション、コンプレッション、フィルター スケーリング、およびボリューム スケーリングが含まれます。

8. 最終ステージ Speaker Output Accumulation では、スピーカー ミックス バッファーが複数のサウンド ソースからのサンプルを収集およびミックスして再生します。このステージでは、オプションのグローバル オーディオ エフェクトを処理できます。

個々の SHAPE ブロックは、コンテキストと実行リストという 2 つの主要なソフトウェア要素で制御されます。メイン メモリに格納されるコンテキストは、状態を保持し、特定の SHAPE ハードウェア ブロック内の処理要素に対する制御を提供します。最初は CPU によって生成されますが、CPU または SHAPE ACP のいずれかによって更新できます。コンテキストは、個々のハードウェア ブロックの必要に応じて、オーディオ フレームごとに SHAPE サブシステムに読み込まれます。128 サンプルのオーディオ フレーム サイズと 48 kHz のサンプリング レートで、オーディオ チャネルあたり 375 Hz のレートでコンテキストが交換されます。

実行リストは、SHAPE オーディオ プロセッサによって処理されるメタ コマンドで構成されます。プロセッサはプログラム可能で柔軟性があるため、実行リストの形式と機能は柔軟です。一部のメタ コマンドには暗黙的なデータがあり、他のものには明示的な引数があります。メタ コマンドはまた、ハードウェアによって割り当てられるミックス バッファーを使用して、特定の SHAPE ハードウェア ブロックが入力を取得する場所と、出力を書き込む場所を指定します。処理のために SHAPE ハードウェアに送信されるコマンドのリストは、*フローグラフ*と呼ばれ、[ACP の概要](/build/console-features/audio/overviews/acp-overview)に記載されています。図 1 は、4 つの SHAPE アクセラレーター ブロックと、他の主要コンポーネントとの相互作用を示しています。

**図 1.  4 つの SHAPE アクセラレーター ブロックと、他の主要コンポーネントとの相互作用。**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/shape_blocks.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=a56a0204158197c6ac612eb7260c0f17" alt="4 つの SHAPE アクセラレーター ブロック" width="464" height="580" data-path="images/gdk/features/console/shape_blocks.png" />

<a id="ID4EWC" />

## DMA

Direct Memory Access (DMA) システムは、float から integer および integer から float への自動変換を伴う読み書き機能をサポートします。DMA システムは、128 サンプル ブロック内の非インターリーブ サンプルを含むサーキュラー バッファーを使用します。

DMA プロセッサは、SHAPE エンジンがミックス バッファーからメイン システム メモリにデータを送信したり、メイン システム メモリから追加処理のためにミックス バッファーにデータを取得したりすることを可能にします。DMA はブロックごとに実行されます。オーディオ フレーム 1 つ分のデータが一度に転送されます。ブロック インターリーブされたデータをサポートするために、スキップ値は、サンプルの読み書き時にシステム メモリ内でスキップされるオーディオ フレーム ブロックの数を (ベース アドレスから) 指定します。このため、マルチチャネル ストリームには、チャネルごとに 1 つの DMA コンテキストが必要です。

オーディオ データ サンプルは、DMA コンテキスト `FloatConvert` フラグで指定されるように、常に 32 ビット値として、integer または float のいずれかとして読み書きされます。データ帯域幅を減らすため、DMA の方向 (読み取りまたは書き込み) は、DMA コンテキストではなく、DMA コマンドで指定されます。DMA エンジンは信号処理を持ちませんが、float を integer に、integer を float に変換できます。これにより、アプリケーション CPU が浮動小数点形式でデータ サンプルを処理できます。

DMA バッファーのサイズを計算するには、次の式を使用します。

```cpp theme={null}
fullBufferSizeInBytes = 128 * 4 * numChannels * numFrames  
```

読み書きポインターは、次のようにインクリメントされます。

```cpp theme={null}
readPointer = (readPointer + 1) % numFrames  
```

```cpp theme={null}
writePointer = (writePointer + 1) % numFrames  
```

オーディオ バッファー内のアドレスは、次のように計算されます。

```cpp theme={null}
readAddress = audioBuffer + (128 * 4 * ((readPointer * numChannels) + channel))  
```

```cpp theme={null}
writeAddress = audioBuffer + (128 * 4 * ((writePointer * numChannels) + channel))  
```

たとえば、DMA バッファーに 3 フレームと 4 チャネルが含まれる場合、バッファーは図 2 に示すように編成され、各チャネル ブロックに 128 個の連続サンプルが含まれます。

**図 2.  DMA バッファー。**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/audio_dma_buffer.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=687279036fc31562a1e09b3e656214d4" alt="オーディオ DMA バッファー" width="900" height="113" data-path="images/gdk/features/console/audio_dma_buffer.png" />

SHAPE クロックは CPU クロックとは独立しているため、レイテンシーが要因となる可能性があります。ハードウェアからソフトウェア、およびソフトウェアからハードウェアへの遷移では 2.66 ms のレイテンシーが発生します。重要なコードを同期し、特定のサウンドに複数の遷移を使用する場合は、サウンド レンダリングを同期するために CPU クロックベースの遅延を実装することを検討してください。さらに、CPU 使用率を減らすために、レイテンシー耐性のあるサブミックスの開発を検討してください。

<a id="ID4EYD" />

## XMA

XMA フォーマットは、可変ビット レートおよび圧縮を伴うモノラル、ステレオ、およびインターリーブされたマルチチャネル サウンドをサポートします。XBOX 360 の XMA 実装に対して、クロック レートの向上 (たとえばピッチ シフト機能で 40% の改善) や、音声数の 320 から 512 への増加など、いくつかの改善が加えられています。

XMA デコーダー ブロックは、メイン メモリ内の XMA データの一部をデコードし、PCM データをメイン メモリ内の XMA デコード バッファーに返します。XMA デコーダー ブロックは、他の SHAPE コンポーネントとのインターフェイス用の小さな状態関連の拡張を除き、XBOX 360 XMA デコーダー ブロックと同一です。

XMA デコーダー レジスタ ブロックは、各音声のデコード出力に関連する状態情報で拡張されています。XMA コンテキストあたり 5 ビットが、PCM 出力バッファーで未消費のまま残っているオーディオ データの量を指定します。これらのレジスタは、XMA デコーダー ブロック内に実装されています。これにより、メイン メモリを読み取ることなく、SRC のコンテキストをロックするのに十分なサンプルがあるかどうかを判定するために、常に利用可能になります。

<Note>xWMA は SHAPE ではサポートされていませんが、`XAudio2` を使用することでサポートされます。</Note>

<a id="ID4EFE" />

## PCM

Linear Pulse Code Modulation (PCM) は、48 kHz で最大 7.1 サラウンド サウンドをサポートします。ユーザーのサウンド システムが、たとえば 5.1 サラウンド サウンドまたはステレオの場合、ACP はダウンミックスを行います。S/PDIF 出力がサポートされます。

16 ビット モノラルまたはステレオ integer、32 ビット モノラル float、または 32 ビット モノラル integer (左詰めで 24 ビット、または下位 8 ビットがマスクされた 32 ビット) を含むリニアおよびサーキュラー PCM バッファーもサポートされています。

<a id="ID4EOE" />

## Sample Rate Convertor (SRC) ブロック

SRC ブロックは、integer ベースのサンプル レート変換を実行し、出力データをミックス バッファーに書き込みます。SRC は通常、楽器のエミュレーション、ソースよりも 1 オクターブ低いまたは高い入力サンプルへの変換、ドップラー効果や他のエフェクトに使用されます。

SRC ブロックは、システム メモリから 32 ビット浮動小数点 PCM データまたは 16 ビット、24 ビット、または 32 ビットの固定小数点データのいずれかを読み取ります。入力データについては、ブロックは XMA ハードウェア デコーダーの出力またはソフトウェアで保持されているデータのいずれかを取ることができます。

XMA デコーダーと密接に統合されているため、SRC ブロックは、メイン メモリを読み取ることなく、XMA デコード バッファー内のデコード済み PCM データのサンプル数がオーディオ フレームのサンプルを作成および完了するのに十分かどうかを判定できます。

SRC はモノラルまたはステレオ モードで動作します。PCM データはメモリから読み取られ、サンプル レート変換のために共通の 24 ビット固定小数点フォーマットに変換されます。出力は、モードに応じて 1 つまたは 2 つのミックス バッファーに書き込まれます。

ステレオ データは、16 ビット データのインターリーブされたストリームとしてメモリに格納されます。左チャネルは各 32 ビット ワードの下位 16 ビットにあり、右チャネルは上位 16 ビットにあります。ステレオ モードでもまた、PCM データが読み取られ、同時に非インターリーブ化されます。左チャネル データ (サンプル 0,2,4,6...) が処理され、1 つのミックス バッファーに出力されます。右チャネル データ (サンプル 1,3,5,7...) は 2 番目のミックス バッファーに書き込まれます。図 3 は、サンプル レート変換モードを示しています。

**図 3.  サンプル レート変換モード。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/console/src_modes.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=ef6fd2d2a8c90d8675a6ab62ec975a0a" alt="サンプル レート変換モード" width="469" height="363" data-path="images/gdk/features/console/src_modes.png" />

SRC ブロックへの入力は、384 kHz マイナス イプシロンを超えない任意のサンプリング レートにすることができます。ただし、出力は 48 kHz の一定レートになります。イプシロンは、要求される integer 値とハードウェアで使用される浮動小数点値の間の小さいデルタです。

SHAPE は、オーディオ フレームあたり最大 512 チャネル (モノラルとステレオの任意のミックス) の SRC を処理できます。

SRC は線形および多相補間、モノラルおよびステレオ、および 1:16 (4 オクターブ ダウン) から 3.99:1 (ほぼ 2 オクターブ アップ) までのリサンプリング範囲をサポートします。

<a id="ID4ECF" />

## イコライゼーションとコンプレッション

コンプレッサーは、入力レベルを監視し、動的ゲイン値を作成することで、信号のダイナミック レンジを制限します。次に、コンプレッサーは、入力信号の現在のレベルに応じて、ゲイン値を信号の乗数として使用し、適切にスケーリングします。言い換えれば、コンプレッサーは、入力信号を常に監視し、自身を調整する自動音量制御です。

コンプレッサーは、特定のしきい値を超える信号にのみ作用します。しきい値未満の信号は、変更されずに通過します。しきい値は、EQComp コンテキスト データの一部としてアプリケーションによって設定されます。コンテキスト内のプログラム可能な制御は、コンプレッションまたはエクスパンションを実行するために使用されます。

コンプレッサーは、入力レベルと出力レベルの比率を指定するパラメーターに従って、サウンド データを変更します。この比率は、入力信号がしきい値を超えた場合に、入力信号に対して実行される減衰の程度を表します。例:

* 2:1 では、しきい値を超える 2 dB ごとに、コンプレッサーはしきい値レベルを 1 dB 超えた値を出力します。
* 1:1 では、コンプレッサーは本質的にオフです。

比率は、コンテキスト データの一部としてアプリケーションによって設定されます。次の図 (図 4) は、入力信号に対するコンプレッサーの効果を示しています。しきい値未満では、出力は入力と等しくなります。しきい値を超えると、コンプレッサーは、比率で指定された量 (約 2:1) だけ出力を低減します。

**図 4.  入出力ボリューム曲線。**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/eqcomp_threshold.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=98e67769541f0ef0e66e633dad1c9207" alt="入出力ボリューム曲線" width="433" height="309" data-path="images/gdk/features/console/eqcomp_threshold.png" />

`attack` および `release` パラメーターは、コンプレッサーがどれだけ迅速にアクティブ化されるかを指定します。つまり、しきい値を超えるサウンドを、比率で指定された量だけ完全に減衰するのに、どれだけの時間がかかるかを指定します。`Attack` および `release` はミリ秒単位で指定され、しきい値を超えたりしきい値を下回ったりする信号に応答してコンプレッサーが出力ゲインをどれだけ迅速に変化させるかに対応します。これらの調整は、線形または対数ベースにすることができます。

次の図 (図 5) は、入力が `attack` で指定された時間だけしきい値を超えるまで、目的の出力レベルが達成されないことを示しています。また、入力が `release` で指定された時間だけしきい値を下回るまで、入力と出力がユニティに戻らないことも示しています。

**図 5.  attack/release のタイミング。**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/eqcomp_attack.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=b657d17c473c879eaab036ab7ec48893" alt="attack/release のタイミング" width="459" height="233" data-path="images/gdk/features/console/eqcomp_attack.png" />

その後、入力は現在の出力ゲインで乗算されます。この最初の乗算が、実際のコンプレッションを実行します。つまり、入力振幅に応じた時間変化関数を通じた信号のスケーリングです。

もう 1 つの追加のゲイン スケーリングがあり、これが最終ステップです。*メイクアップ ゲイン*は、アプリケーションによって設定される不変の値です。コンプレッション、特に低しきい値では、比較的低いゲインの信号が結果として生じる可能性があるため、メイクアップ ゲインは信号を使用可能な範囲に戻すために使用されます。

コンプレッサーには、`RMS` という 1 つの追加パラメーターがあります。通常モードでは、入力レベルは瞬時的で、すべてのサンプルに対して計算されます。`RMS` モードでは、前の 128 サンプルにわたって移動平均 (`RMS` 値の近似値) が保持されます。現在の入力サンプルの絶対レベルではなく、この移動平均が入力レベルとして使用されます。

EQ/コンプレッサー-エクスパンダー ブロックには、直列に配置された 2 つの別々の処理ユニット (3 バンド プログラマブル イコライザーとダイナミック レンジ コンプレッサー) が含まれます (図 6)。このブロックは、サウンドの周波数とダイナミック レンジを制御するために使用され、1 つまたは 2 つのミックス バッファーから入力を取得します。

* 1 つの入力は、処理されるオーディオ信号です。
* *サイドチェーン*と呼ばれる 2 番目の入力は、オーディオ コンプレッションを決定するために使用されるオプションの制御信号です。

イコライザーには、完全にプログラム可能な係数があります。ソフトウェアは、イコライザーの伝達関数を完全に制御できます。

**図 6.  イコライザーは、A、B、C として指定される 3 つの直列 biquad フィルターとして実装されます。**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/eqcomp_biquad.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=fe84848c225aa369e39865efa0d1b4a5" alt="3 つの biquad フィルター" width="735" height="59" data-path="images/gdk/features/console/eqcomp_biquad.png" />

各 biquad フィルターは、次の式を実装します。ここで *x* は入力、*y* は出力、*a1*、*a2*、*b0*、*b1*、*b2* は係数です。係数は [SHAPE\_EQCOMP\_CONTEXT](/reference/audio/shapeeqcompcontext/structs/shape_eqcomp_context) 構造体でアクセスできます。

```
y[n] = (b0/a0)*x[n] + (b1/a0)*x[n-1] + (b2/a0)*x[n-2] - (a1/a0)*y[n-1] - (a2/a0)*y[n-2]  
```

通常、サウンドに対してイコライゼーションが実行されると、特定の周波数の領域がカットまたはブーストされます。周波数がカット (減衰) される場合、問題は発生しません。出力信号は入力と等しいか、より低いレベルになります。ただし、周波数がブーストされると、信号のピーク間ダイナミック レンジに対応する増加がしばしば発生します。たとえば、低音を 6 dB ブーストすると、入力よりも高い出力ゲインが生じます。入力信号が既にフル スケール (-0 dBFS) だった場合、出力は必ず最大値を超えます。

このため、3 段カスケード biquad EQ セクション内のダイナミック レンジは、2 進小数点の左側に追加の 8 ビットの精度を維持します。したがって、EQ 処理中に s.23 入力フォーマットは s8.23 になります。追加範囲により、各 EQ ステージは、ほとんどの場合オーディオ出力を飽和させることなく、ゲイン ブーストを提供できます。ただし、最大入力条件下で、3 つのステージすべてに +18 dB の最大ゲインが適用されると、3 番目のステージが飽和する可能性があり、その場合、ハードウェアはこのピーク オーバーフロー イベントを検出します。

各 biquad のフィルター係数 (b0、b1、b2、a1、a2) は 24 ビット integer です。これにより、+/- 7.998 までの係数範囲が可能になり、許可されるフィルターのタイプ、20 Hz から 18 kHz の周波数範囲、および -18 dB から 18 dB のゲイン範囲の係数を提供するのに適しています。

コンプレッサー-エクスパンダーは、3 つのサイドチェーン モードのいずれかで動作できます。

* Normal モード (図 7) では、ミックス バッファーからの単一のオーディオ入力があります。入力はイコライザーを通り、その後コンプレッサーで処理され、ミックス バッファーに出力されます。

  **図 7.  Normal モード。**

  <img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/eqcomp_normal.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=be6088e111b99afb2055ec8f6bb00c37" alt="Normal モード" width="735" height="144" data-path="images/gdk/features/console/eqcomp_normal.png" />

* Internal モード (図 8) では、入力信号はコンプレッサーのオーディオ入力に直接供給され、分岐してイコライザーに送信されます。イコライザーから、コンプレッサーのサイドチェーン入力に送信されます。

  **図 8.  Internal モード。**

  <img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/eqcomp_internal.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=ed49c3cd88dc5fee2317e873e819fe1d" alt="Internal モード" width="735" height="137" data-path="images/gdk/features/console/eqcomp_internal.png" />

* External モード (図 9) では、2 つの別々のミックス バッファーから 2 つの別々の入力信号が使用されます。入力信号はイコライザーを通り、コンプレッション ブロックのオーディオ入力に供給されます。サイドチェーン入力信号は、コンプレッサーのサイドチェーン入力に直接供給されます。

  **図 9.  External モード。**

  <img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/eqcomp_external.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=cf67a63a45209acd9f40730df9fc9ba2" alt="External モード" width="735" height="146" data-path="images/gdk/features/console/eqcomp_external.png" />

SHAPE は、オーディオ フレームあたり最大 512 の EQCOMP コンテキストを処理できます。

<a id="ID4EBH" />

## フィルター/ボリューム ブロック (FLTVOL)

FLTVOL は以下の目的で使用されます。

* オブジェクトの周りまたはオブジェクトを通じてサウンドが遮蔽されるモデリング

* サウンドが到達する方向をモデル化するために、複数のスピーカーにサウンドのエネルギーを分配

FLTVOL は、ミックス バッファーから単一チャネルの入力データを取得し、フィルタリングおよびボリューム スケーリングを行い、ミックス バッファーに出力を書き込みます。通常、複数のフィルター/ボリューム制御が使用され、サラウンド サウンド パンなどの 1 入力・多出力パンを生成します。パンナーは通常、サウンドを取り、*n* スピーカー パンニングと 1 つ以上のリバーブ エフェクトを実行するために使用されます。ステート変数フィルターを使用すると、タイトルは強化された距離エフェクトや I3DL2 スタイルのオクルージョンおよび遮蔽エフェクトを簡単に作成できます。

その性質上、ステート変数フィルターは、中間値が 1.0 または -1.0 を超えるような共振を作成する可能性があります。中間値の飽和によって作成される問題を軽減するため、FLTVOL には入力信号にプログラム可能な量のヘッドルーム スケーリングが適用され、出力時に補正されます。スケーリングは、データを特定のビット数だけ算術右シフトすることで達成されます。コンテキストのヘッドルーム フィールドは、FLTVOL 処理前に入力信号が受け取る右シフトのビット数 (0、1、2、または 3) を指定します。たとえば、ヘッドルーム値 *3* が指定される場合、ステート変数フィルターは、内部的に作成される共振とオーバーフロー用に、追加の 3 ビット (18 dB) のヘッドルームを維持できます。

入力データを右にシフトすると、必然的に下端の精度が低下します。入力オーディオ信号の下位ヘッドルーム ビットは永久に失われます。したがって、ステート変数フィルターで内部飽和が発生している場合にのみ、ヘッドルーム ビットをゼロ以外として指定してください。そのためには、FLTVOL コンテキストの Internal Overflow ビットの値をチェックしてください。元のソース データが 16 ビットの場合 (たとえば、元のソース データが XMA の場合)、下位ビットはとにかくゼロ パディングされているため、通常はサウンドに顕著な変化なくヘッドルーム ビットを最大 *3* に設定できます。

柔軟なステート変数フィルターの実装により、興味深いオーディオ エフェクトとバリエーションを作成するのに役立つ、音声への共振フィルタリングの適用も可能になります。エントリとエグジットの設定ポイント間のスムーズな遷移を提供するために、フィルター パラメーターとボリューム属性は、サンプルごとに徐々に調整されます。FLTVOL ブロックは Chamberlin フィルターとして実装されており、High-pass、Low-pass、および可変 Q (帯域幅) 制御を備えた Band-pass の 3 つのモードを提供します。Chamberlin フィルターのパラメーターは、次のように計算されます。

```
f := 2*Sin( ( PI * FC )/FS)  

q := 1/Q, where Q ranges from .5 to 5  
```

`f` および `q` パラメーターは、SHAPE ブロック外のソフトウェアによって計算されます。係数が更新されるとき、1 オーディオ フレームの過程で新しい値にランプされます。制御ビットは、FLTVOL ブロックの最終出力として使用される出力 (band reject、High-pass、Band-pass、または Low-pass) を決定するために使用されます。

各チャネルまたはストリームのコンテキスト データは、システム メモリに格納されます。パフォーマンスは 2560 の 48 kHz 同時ストリームに制限されますが (つまり、SHAPE はオーディオ フレームあたり最大 2560 の FLTVOL コンテキストを処理できます)、ストリーム再利用のシナリオを簡素化するため、メモリでアドレス指定可能なコンテキストの数はより大きくなっています。

フィルタリング動作は、`XAudio2` のものと同一になるように設計されています。

<a id="ID4EYH" />

## ミックス バッファー

ミックス バッファーには、3 つの主な目的があります。

* ミックス バッファーは、システムの各スピーカー出力 (または個々のプレイヤー) の最終的なミキシング先として機能します。各サウンドが処理されると、その後続の出力がこれらのバッファーにミックスされます。

* ハードウェア ブロック間でオーディオ データのバッファーが渡されるとき、ミックス バッファーは一時的な保管場所として機能します。

* DMA エンジンと連携して、ミックス バッファーは、SHAPE ハードウェアとオーディオ サブシステムからメイン システムにデータを渡す仕組みとして、およびメイン システム メモリから SHAPE ハードウェアとオーディオ サブシステムに戻すデータを渡す仕組みとして機能します。

SHAPE システムは、ミックス バッファーを広範に使用します。128 の物理チャネルにレンダリングする最大 8192 の同時仮想ミックス バッファー (ID 0 から 8191) が存在します。ミキシングは、ハードウェア アキュムレーターを使用し、メモリとの間の DMA を必要とせずに実行できます。ミックス バッファーはメータリングとクリッピングをサポートします。

<a id="ID4ELAAC" />

## オーバーフロー、マグニチュード、飽和

タイトルのオーディオ エンジンでは、ヘッドルームの管理が非常に困難な場合があります。このため、各 SHAPE ブロックは、信号オーバーヘッドとゲインに関連する状態を維持します。SRC 以外の各ブロックは、処理中に内部飽和が発生したかどうかを示すフラグを維持します。

内部飽和フラグに加えて、各ハードウェア ブロックはまた、ハードウェア ブロックの出力の大きさを表す 2 つの 4 ビット数値を維持します。マグニチュードは、オーディオ フレーム中のピーク出力を判定し、ピークの絶対値の先行ゼロをカウントすることによって計算されます。1 つの 4 ビット数値は永続的なピーク マグニチュードで維持され、もう 1 つはオーディオ フレームごとにハードウェアによってリセットされます。

各個別のハードウェア ブロックのピーク マグニチュードの監視に加えて、ミックス バッファーのピーク マグニチュードも維持されます。ハードウェア ブロックの出力がミックス バッファーに追加されると、ピーク マグニチュードは同じ方法 (先行ゼロをカウントすることによって) で計算されます。各ハードウェア ブロックの状態は、追加のペアの 4 ビット ピーク マグニチュード値を維持します。これらの値は、ハードウェア ブロックの出力がミックス バッファーに蓄積された後のミックス バッファーのピーク マグニチュードを表します。1 つの 4 ビット数値は、継続的な、永続的なピーク マグニチュードを表します。もう 1 つはオーディオ フレームごとに更新されます。ピーク マグニチュード値は、表現されているのがミックス バッファーの状態であっても、SHAPE ブロックのコンテキストに保存されます。

ピーク マグニチュードは、次の表 (ShapeHardwareContexts.h ファイルにコード化) に従ってエンコードされます。

| バイナリ値            | 説明                                                                                                                                                                          |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| B'0000           | 飽和: 出力の計算からの値が符号付き 24 ビット範囲をオーバーフローし、最も近い極値に置き換えられました。具体的には、8,388,607 (0x7F\_FFFF) より大きい値は 8,388,607 に置き換えられました。あるいは、-8,388,608 (0x80\_0000) より小さい値は -8,388,608 に置き換えられました。 |
| B'0001           | ピークの絶対値が MAX >> 1 (0x3F\_FFFF) より大きくなりました。                                                                                                                                  |
| B'0010           | ピークの絶対値が MAX >> 2 (0x1F\_FFFF) より大きくなりました。                                                                                                                                  |
| B'0011           | ピークの絶対値が MAX >> 3 より大きくなりました。                                                                                                                                               |
| B'0100           | ピークの絶対値が MAX >> 4 より大きくなりました。                                                                                                                                               |
| B'0101           | ピークの絶対値が MAX >> 5 より大きくなりました。                                                                                                                                               |
| B'0110 から B'1101 | 前述のシナリオと同様に、ピークの絶対値が MAX >> 6 から 13 より大きくなりました。                                                                                                                             |
| B'1110           | ピークの絶対値が MAX >> 14 より大きくなりました。                                                                                                                                              |
| B'1111           | ピークの絶対値が MAX >> 14 以下でした。                                                                                                                                                   |

オーバーヘッドを管理し、オーバーフローと飽和を回避するのに役立つように、細粒度のゲイン設定に加えて、出力ミックス バッファーへの蓄積の前に、ハードウェア ブロックの出力に 0 から 7 ビットの右シフトを実行できます。これは、各 SHAPE ハードウェア ブロックのコンテキストで指定されます。

<a id="ID4EDDAC" />

## SHAPE キュー

SHAPE オーディオ プロセッサは、システム ハードウェアとアプリ ハードウェアのインターロックを削減するのに役立つ 2 つのキューを管理します。

1. Command and Control Queue (CCQ) は、可能なときに (通常は現在のオーディオ フレームの処理が完了したときに) 実行する一連のコマンドを SHAPE オーディオ プロセッサに提供するために使用されます。SHAPE 実行リストは、オーディオ フレーム出力ごとに 1 回読み取られます。ただし、CCQ は 1 回だけ読み取られて実行されます。

   CCQ は、SHAPE ハードウェアとハードウェア インターロックを必要とせずに、オーディオ フレーム境界で任意のブロック コンテキスト データを CPU に更新させるためのメカニズムです。この例には、XMA ブロックにさらに多くのビットストリーム データを提供すること、さまざまなブロックのコンテキスト パラメーターを更新すること、および新しい実行リストを指すことが含まれます。これは通常、オーディオ処理フローグラフが変更されるときに行われます。

2. Status and Reporting Queue (SRQ) は、SHAPE オーディオ プロセッサがリアルタイム応答を必要としないさまざまなイベントを CPU に報告するために使用されます。例には、ビットストリーム バッファー消費、エラー、警告およびフラグ、デバッグ データ、パフォーマンス データ、および状態情報の更新が含まれます。

<a id="ID4EMDAC" />

## プログラミングに関する考慮事項

SHAPE ハードウェアへの直接プログラミングは、`IACPHAL` インターフェイスを通じて有効になります。ただし、SHAPE ハードウェア用のオーディオ データの準備プロセスは複雑です。多くのユーティリティ メソッド、構造体、および列挙型が提供されています。これらのユーティリティは、SHAPE ハードウェアを制御するために必要なメソッドのすべてまたはほとんどを提供します。特定の種類のデータを処理するためにコードを修正する必要がまれにあるケースに備えて、Microsoft Game Development Kit (GDK) にはこれらのユーティリティのソース コードが含まれています。

プロジェクトに明示的にインクルードする唯一のヘッダー ファイルは *acphal.h* で、すべてのユーティリティ ヘッダー ファイルを参照します。すべてのユーティリティ関数は、`NO_SHAPE_CONTEXT_VALIDATION` マクロを参照します。このマクロが定義されている場合、すべての検証が省略されます。これは最終小売ビルドに役立ちます。

SHAPE および XMA リソースを `XAudio2` のインスタンスと共有する方法の詳細については、[XAudio2Create](https://learn.microsoft.com/windows/desktop/api/xaudio2/nf-xaudio2-xaudio2create) 関数の Remarks セクションを参照してください。

すべてのユーティリティ メソッドの詳細については、[ACP の概要](/build/console-features/audio/overviews/acp-overview)を参照してください。

<a id="ID4EDEAC" />

### 永続的および非永続的なフローグラフ

フローグラフを永続的または非永続的として処理されるように送信できます。永続的なフローグラフは処理された後、次のフレームで読み書きポインターが進んで他のコンテキスト情報が更新された後に処理が繰り返されるように常駐したままになります。次のいずれかのシナリオでは、永続的なフローグラフを使用してください。

* 各フレームを再組み立てするために大量の CPU 処理が必要な、非常に複雑なフローグラフ
* 長期間にわたって同じ音声の数と構成を持つ、非常に静的なフローグラフ

次のいずれかのシナリオでは、非永続的なフローグラフを使用してください。

* 音声トポロジが頻繁に変わる。
* タイトルのオーディオ ソフトウェア エンジンの処理ケイデンスが SHAPE ハードウェアから切り離されている。つまり、2.667 ms の倍数ではない。
* オーディオ処理をリアルタイムより速く実行したい。つまり、利用可能になり次第、消費されるようにグラフを送信したい。

<a id="ID4E6EAC" />

### 問題のデバッグ

フローグラフを開発する際、メッセージを登録することは、発生する可能性のある問題のデバッグに役立ちます。具体的には、[Connect](/reference/audio/acphal/interfaces/IAcpHal/methods/iacphal_connect) の `NumMessages` パラメーターを使用してください。メッセージ システムは、無効なフローグラフ (`ACP_FLOWGRAPH_TERMINATED_REASON_INVALID_GRAPH`)、ブロックされたコマンド、およびハードウェアのフレーム サイズ 2.667 ms が許可する以上の処理を実行しようとした場合に発生するフレーム アウトなど、さまざまな問題に関する豊富なフィードバックを提供します。タイトルを出荷する前に、送信された各フローグラフの `ACP_MESSAGE_TYPE_FLOWGRAPH_COMPLETED` メッセージを観察して、フローグラフ処理が一貫して成功していることを確認してください。

* [見逃されたメッセージ](#ID4ENFAC)
* [フレーム アウト](#ID4E1FAC)
* [ブロックされたコマンド](#ID4EBGAC)
* [同期の問題](#ID4ENIAC)

<a id="ID4ENFAC" />

#### 見逃されたメッセージ

エンジン状態を駆動するために ACP メッセージを使用し、多くのメッセージを処理する場合は、開発中に [ACP\_MESSAGE](/reference/audio/acphal/structs/acp_message) の `droppedMessageCount` フィールドを検査してください。フィールドの値がゼロ以外の場合は、メッセージ キューがいっぱいで、メッセージがドロップされる必要があったことを示します。このシナリオでは、キューをより速くサービスし、より大きくすることを検討してください。

<a id="ID4E1FAC" />

#### フレーム アウト

オーディオ フレーム (2.667 ms) の終わりに遭遇する前にフローグラフが完了しない理由は多くあります。たとえば、多すぎるフローグラフの処理や、構造化が不十分なフローグラフの処理などです。この不完全なフローグラフは、永続的なフローグラフに対して `ACP_FLOWGRAPH_TERMINATED_TIME_EXCEEDED` メッセージを発生させ、これらの永続的なフローグラフは不完全になります。対照的に、非永続的なフローグラフはこの方法で制約されず、フレームをまたいでも完了するまで実行されます。

<a id="ID4EBGAC" />

#### ブロックされたコマンド

次の表に示すように、いくつかのシナリオで SRC および DMA コマンドがブロックされたとして報告される場合があります (`ACP_MESSAGE_TYPE_SRC_BLOCKED`、`ACP_MESSAGE_TYPE_DMA_BLOCKED`)。

\| コマンド タイプ | ブロックのシナリオ |
\| --- | --- | --- | --- |
\| XMA SRC| 関連する XMA コンテキストにパーサー エラーがあるか、ソース データがありません。エラーは `SHAPE_XMA_ERROR_STATUS_READ_BUFFER_INVALID_VALIDBUFFER_CURRBUF_IS_0` | `SHAPE_XMA_ERROR_STATUS_FRAME_CROSSES_BOUNDARY_INTO_INVALID_READ_BUFFER_VALIDBUFFER_CURRBUF_IS_0` | `SHAPE_XMA_ERROR_STATUS_FRAME_CROSSES_BOTH_READ_BUFFER_BOUNDARIES` です。XMA SRC は、デコード済みデータの不足によってはブロックされません。|
\| PCM SRC| 関連する PCM コンテキストが `SHAPE_PCM_MODE_CIRCULAR` で、ソース データがない。|
\| 読み取り (ミックス バッファーからの DMA)| DMA バッファーがいっぱい。|
\| 書き込み (ミックス バッファーへの DMA)| DMA バッファーが空。|

コマンドがブロックされていると判断されると (処理のために SHAPE キューに追加される前と実行時の両方で発生します)、グラフから削除されるため、オーディオがドロップされる可能性があります。開発中は、フローグラフの処理の改善を検討する最初の場所として、ブロックされたコマンドを使用してください。また、出荷前に、タイトルがコマンドをブロックされないようにすることを確認してください。

DMA コマンドのブロックを防ぐには、オーディオ バッファーが十分に大きく、バッファー サイズに対して定期的な間隔でデータがストリーミングされていることを確認してください。たとえば、一度に 4 つのハードウェア フレームをストリーミングしている場合、それらのフレームの倍数 (少なくともダブル バッファーとして 8) がバッファー内にあり、ハードウェアがタイトルの読み取りポインターの先を書き込めるようにしてください。あるいは、次のフローグラフを送信する前にバッファーを空にすることを強制することもできます。消費し、DMA 読み取りポインターを更新し、次にフローグラフを送信します。

SRC コマンドには 3 つのモードがあります。

* `SHAPE_SRC_COMMAND_TYPE_START` は、フローグラフのほぼすべての SRC コマンドに使用されます。通常の処理を実行し、現在のフローグラフの後にさらなるオーディオ データが続くことを期待します。
* `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` は、ソース XMA または PCM データの処理を直ちに停止するために使用されます。SRC は、このフレーム用にゼロ化されたバッファーを出力します。
* `SHAPE_SRC_COMMAND_TYPE_STOP_END` は、音声の最後のパケットを示すために使用されます。

音声の最後のパケットが `STOP_END` または `STOP_IMMEDIATE` で送信されない場合、SRC コマンドは完了せず、アクティブなフローグラフが停止します。永続的なフローグラフはオーディオ フレームの終わりで終了し、非永続的なフローグラフは決して完了しません。

<a id="ID4ENIAC" />

#### 同期の問題

コンテキストとコマンドに対する SHAPE ハードウェアの消費慣行を尊重しない場合、同期の問題が発生する可能性があります。タイトルは ACP に割り当てられたメモリへの完全なアクセスを維持しますが、使用中のコンテキスト構造体を変更しないように注意してください。[SubmitCommand](/reference/audio/acphal/interfaces/IAcpHal/methods/iacphal_submitcommand) を使用して、特定のフレーム、次のフレームの先頭、またはできるだけ早く発生するようにコマンドを送信できます。

<Note>「できるだけ早く」のシナリオは、依然としてタイトルの CPU 処理と非同期です。一部のコマンドはすぐには完了しない場合があります。たとえば、コンテキストが割り込み不可能な操作の途中にある場合です。コマンドが実際に処理されたことを確認するには、`ACP_MESSAGE_TYPE_COMMAND_COMPLETED` を待ってください。</Note>

詳細については、[SHAPE を使いこなす: オーディオ フローグラフ構築のベスト プラクティス](/build/console-features/audio/overviews/best-practices-audio-flowgraph-construction)を参照してください。


## Related topics

- [概要](/ja-jp/build/console-features/audio/overviews/index.md)
- [SHAPE_PCM_FORMAT](/ja-jp/reference/audio/shapepcmcontext/enums/shape_pcm_format.md)
- [SHAPE_PCM_MODE](/ja-jp/reference/audio/shapepcmcontext/enums/shape_pcm_mode.md)
- [SHAPE_PCM_CONTEXT](/ja-jp/reference/audio/shapepcmcontext/structs/shape_pcm_context.md)
- [SHAPE_FLOWGRAPH_DMA_COMMAND](/ja-jp/reference/audio/shapeflowgraph/structs/shape_flowgraph_dma_command.md)
