> ## 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.

# ACP 概觀

> 音訊控制處理器 (ACP) 以及在 XBOX One 主機上管理 SHAPE 音訊流程圖之 acphal 程式庫的程式設計指南。

本主題提供用於指揮音訊控制處理器 (Audio Control Processor，ACP) 之流程圖的說明和範例。

<a id="ID4EX" />

## ACP 概觀

本節說明 ACP 的程式設計介面。

`acphal` 程式庫 (*acphal.lib*) 定義了可調整硬體音訊處理引擎 (Scalable Hardware Audio Processing Engine，SHAPE) 的 API 集。Microsoft Game Development Kit (GDK) 中也包含一系列音訊公用程式和原始程式碼，協助您準備可搭配 SHAPE 使用的音訊資料。公用程式標頭定義了下列項目：

* 每種支援資料格式的內容結構

* 一組完整的函式，可用來讀取和寫入這些內容

請在您的應用程式中定義至少一個流程圖，以將音訊資料路由*通過* SHAPE 區塊。ACP 會管理 SHAPE 區塊並確保效率。

如需 API 集的詳細資訊 (包括公用程式檔案中宣告的結構和列舉)，請參閱 [AcpHal](/zh-TW/reference/audio/acphal/acphal_members) 參考。

如需 SHAPE 架構的詳細資訊，請參閱 [SHAPE 概觀](/zh-TW/build/console-features/audio/overviews/shape-overview)。

在遊戲專案的原始程式檔中，請務必包含 *ShapeContext.h* 檔案，而不是個別的內容標頭檔。

本主題內容：

* [流程圖](#ID4EVB)
* [DMA 公用程式](#ID4EZH)
* [EQ 壓縮器公用程式](#ID4EIAAC)
* [濾波器音量公用程式](#ID4EWAAC)
* [PCM 公用程式](#ID4EEBAC)
* [SRC 公用程式](#ID4ESBAC)
* [XMA 公用程式](#ID4EACAC)
* [目標值](#ID4EXEAC)
* [執行緒安全](#ID4E3NAC)
* [針對 PCM 和 XMA 資料使用 SRC 的指導方針](#ID4EUPAC)
* [暫停和繼續遊戲](#ID4E5BAE)

<a id="ID4EVB" />

### 流程圖

若要使用 SHAPE，遊戲通常會建立 SHAPE 流程圖。如需替代方法的說明，請參閱 [XMA 公用程式](#ID4EACAC)一節。SHAPE 流程圖是一個命令陣列 (每個 SHAPE 區塊一個命令) 以及隨附的內容資料，用來描述個別區塊的作業順序及其處理的資料。ACP 會使用流程圖中的資料，正確排程 SHAPE 區塊內的作業。

遊戲負責建置流程圖並將其提交至 ACP。若要建置流程圖，請使用 [ShapeFlowGraph (流程圖公用程式方法)](/zh-TW/reference/audio/shapeflowgraph/shapeflowgraph_members)。

在下列圖中，綠色區塊代表 SHAPE 元件，青色區塊是來源素材，而有標籤的黃色圓圈則是硬體混音緩衝區。

* [3D 音效](#ID4EHC)
* [軟體音訊引擎的前端](#ID4ETC)
* [轉譯音訊](#ID4E6C)
* [流程圖剖析](#ID4EHF)
* [更新流程圖](#ID4EHG)
* [多個流程圖](#ID4ELH)

<a id="ID4EHC" />

#### 3D 音效

**圖 1. 兩個語音，各自在兩個輸出之間平移，並傳送至一個共同輸出。**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/flowgraph_pan.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=717d40735192142f7a194f6be5a27576" alt="兩個語音的流程圖" width="985" height="465" data-path="images/gdk/features/console/flowgraph_pan.png" />

在程式碼中，此流程圖可以表示如下。

```cpp theme={null}
        typedef enum mixBuffers
        {
          noBuffer         =   0,
          mixBuffer_1      =   1,
          mixBuffer_2      =   2,
          mixBuffer_3      =   3,
          mixBuffer_4      =   4,
          mixBuffer_5      =   5,
          mixBuffer_6      =   6,
          mixBuffer_7      =   7,
          mixBuffer_8      =   8,
          mixBuffer_9      =   9,
          mixBuffer_10     =   10,
          mixBuffer_11     =   11
        };
        
        typedef enum DMAcontexts
        {
          DMAcontext_0    = 0,
          DMAcontext_1    = 1,
          DMAcontext_2    = 2,
          DMAcontext_3    = 3,
          DMAcontext_4    = 4,      
        };
        
        typedef enum FLTVOLcontexts
        {
          FLTVOLcontext_0    = 0,
          FLTVOLcontext_1    = 1,
          FLTVOLcontext_2    = 2,
          FLTVOLcontext_3    = 3,
          FLTVOLcontext_4    = 4,    
          FLTVOLcontext_5    = 5,
          FLTVOLcontext_6    = 6,
          FLTVOLcontext_7    = 7,  
        };
                
        typedef enum EQcontexts
        {
          EQcontext_0    = 0,
          EQcontext_1    = 1,      
        };
        
        typedef enum SRCcontexts
        {
          SRCcontext_0    = 0,
          SRCcontext_1    = 1,      
        };
        
        typedef enum XMAcontexts
        {
          XMAcontext_0    = 0,
          XMAcontext_1    = 1,      
        };
        
        //
        // Command structure to be initialized.
        //
        #define nSHAPE_3Dpan_commands       28
        //
        SHAPE_FLOWGRAPH_COMMAND cmd[nSHAPE_3Dpan_commands];
        
        //
        // Shared mix buffer.
        //

        // SetShapeAllocMixBufferCommand parameters:
        //                           command,    virtualID,      numIn, numOut,   attenuation
        SetShapeAllocMixBufferCommand(&cmd[0],   mixBuffer_1,     2,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);

        //
        // Mix buffers for voice A.
        //

        // SetShapeAllocMixBufferCommand parameters:
        //                           command,    virtualID,      numIn, numOut,   attenuation
        SetShapeAllocMixBufferCommand(&cmd[1],   mixBuffer_2,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[2],   mixBuffer_3,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[3],   mixBuffer_4,     1,      3,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[4],   mixBuffer_5,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[5],   mixBuffer_6,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);

        //
        // Voice A.
        //

        // SetShapeSrcXmaCommand parameters:
        //                     command,      contextID,            XMAContextID,       leftorMonoMixBuffer, rightMixBuffer
        SetShapeSrcXmaCommand( &cmd[6],      SRCcontext_0,         XMAcontext_0,       mixBuffer_2,         noBuffer);

        // SetShapeFiltVolCommand parameters:
        //                     command,      contextID,          inputMixBuffer, outputMixBuffer
        SetShapeFiltVolCommand(&cmd[7],      FLTVOLcontext_0,    mixBuffer_2,    mixBuffer_3   );

        // SetShapeEqCompCommand parameters:
        //                  command,         contextID,     inputMixBuffer, sidechainMixBuffer, outputMixBuffer
        SetShapeEqCompCommand( &cmd[8],      EQcontext0,    mixBuffer_3,   noBuffer,           mixBuffer_4);

        // SetShapeFiltVolCommand parameters:
        //                  command,       contextID,            inputMixBuffer,   outputMixBuffer
        SetShapeFiltVolCommand(&cmd[9],    FLTVOLcontext_1,      mixBuffer_4,   mixBuffer_5   );
        SetShapeFiltVolCommand(&cmd[10],   FLTVOLcontext_2,      mixBuffer_4,   mixBuffer_6   );
        SetShapeFiltVolCommand(&cmd[11],   FLTVOLcontext_3,      mixBuffer_4,   mixBuffer_1   );

        //
        // Mix buffers for voice B.
        //

        // SetShapeAllocMixBufferCommand parameters:
        //                           command,     virtualID,      numIn, nmmOut,   attenuation
        SetShapeAllocMixBufferCommand(&cmd[12],   mixBuffer_7,      1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[13],   mixBuffer_8,      1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[14],   mixBuffer_9,      1,      3,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[15],   mixBuffer_10,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[16],   mixBuffer_11,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);

        //
        // Voice B.
        //

        // SetShapeSrcXmaCommand parameters:
        //                     command,    contextID,            XMAContextID,         leftorMonoMixBuffer, rightMixBuffer
        SetShapeSrcXmaCommand( &cmd[17],   SRCcontext_1,         XMAcontext_1,         mixBuffer_7,         noBuffer);

        // SetShapeFiltVolCommand parameters:
        //                     command,    contextID,            inputMixBuffer, outputMixBuffer
        SetShapeFiltVolCommand(&cmd[18],   FLTVOLcontext_4,      mixBuffer_7,    mixBuffer_8   );

        // SetShapeEqCompCommand parameters:
        //                     command,    contextID,       inputMixBuffer, sidechainMixBuffer, outputMixBuffer
        SetShapeEqCompCommand( &cmd[19],   EQcontext1,      mixBuffer_8,    noBuffer,           mixBuffer_9);

        // SetShapeFiltVolCommand parameters:
        //                     command,    contextID,            inputMixBuffer, outputMixBuffer
        SetShapeFiltVolCommand(&cmd[20],   FLTVOLcontext_5,      mixBuffer_9,    mixBuffer_10   );
        SetShapeFiltVolCommand(&cmd[21],   FLTVOLcontext_6,      mixBuffer_9,    mixBuffer_11   );
        SetShapeFiltVolCommand(&cmd[22],   FLTVOLcontext_7,      mixBuffer_9,    mixBuffer_1   );

        //
        // DMA all outputs.
        //

        // SetShapeDmaCommand parameters:
        //                     command,       contextID,         mixBuffer,      write
        SetShapeDmaCommand(    &cmd[23],      DMAcontext_0,      mixBuffer_1,    true);
        SetShapeDmaCommand(    &cmd[24],      DMAcontext_1,      mixBuffer_5,    true);
        SetShapeDmaCommand(    &cmd[25],      DMAcontext_2,      mixBuffer_6,    true);
        SetShapeDmaCommand(    &cmd[26],      DMAcontext_3,      mixBuffer_10,   true);
        SetShapeDmaCommand(    &cmd[27],      DMAcontext_4,      mixBuffer_11,   true);  
```

<a id="ID4ETC" />

#### 軟體音訊引擎的前端

**圖 2.  軟體引擎的基本前端。使用此模型的所有語音可能都會使用相同的結構。**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/flowgraph_frontend.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=d91f5904751f33337ccc9673e6206825" alt="軟體音訊引擎的基本前端" width="648" height="105" data-path="images/gdk/features/console/flowgraph_frontend.png" />

在程式碼中，此流程圖可以表示如下。

```cpp theme={null}
        typedef enum mixBuffers
        {
          noBuffer      =   0,
          mixBuffer_1   =   1,
          mixBuffer_2   =   2,
          mixBuffer_3   =   3
        };
        
        typedef enum DMAcontexts
        {
          DMAcontext_0    = 0,  
        };
        
        typedef enum FLTVOLcontexts
        {
          FLTVOLcontext_0   = 0,
        };
                
        typedef enum EQcontexts
        {
          EQcontext_0    = 0,     
        };
        
        typedef enum SRCcontexts
        {
          SRCcontext_0    = 0,  
        };
        
        typedef enum XMAcontexts
        {
          XMAcontext_0    = 0,   
        };
        
        //
        // Command structure to be initialized.
        //
        #define nSHAPE_frontend_commands        7
        //
        SHAPE_FLOWGRAPH_COMMAND cmd[nSHAPE_frontend_commands];
        
        //
        // Mix buffer allocation for the voice.
        //

        // SetShapeAllocMixBufferCommand parameters:
        //                            command,   virtualID,      numIn,  numOut,   attenuation
        SetShapeAllocMixBufferCommand(&cmd[0],   mixBuffer_1,    1,        1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[1],   mixBuffer_2,    1,        1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[2],   mixBuffer_3,    1,        1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);

        //
        // SHAPE blocks.
        //

        // SetShapeSrcXmaCommand parameters:
        //                     command,      contextID,            XMAContextID,          leftorMonoMixBuffer, rightMixBuffer
        SetShapeSrcXmaCommand( &cmd[3],      SRCcontext_0,         XMAcontext_0,          mixBuffer_1,         noBuffer);

        // SetShapeEqCompCommand parameters:
        //                     command,      contextID,       inputMixBuffer, sidechainMixBuffer,   outputMixBuffer
        SetShapeEqCompCommand( &cmd[4],      EQcontext_0,     mixBuffer_1,   noBuffer,             mixBuffer_2);

        // SetShapeFiltVolCommand parameters:
        //                     command,      contextID,           inputMixBuffer, outputMixBuffer
        SetShapeFiltVolCommand(&cmd[5],      FLTVOLcontext_0,     mixBuffer_2,   mixBuffer_3   );

        // SetShapeDmaCommand parameters:
        //                     command,   contextID,         mixBuffer,    write
        SetShapeDmaCommand(    &cmd[6],   DMAcontext_0,      mixBuffer_3,   true   );  
```

<a id="ID4E6C" />

#### 轉譯音訊

若要轉譯音訊

1. 建立類似先前範例中所示的流程圖，定義要處理的音訊圖。

2. 建立內容結構，定義流程圖將如何處理以及處理哪些內容。

3. 使用 [SubmitCommand](/zh-TW/reference/audio/acphal/interfaces/IAcpHal/methods/iacphal_submitcommand) 方法將流程圖提交至 ACP。根據 `SubmitCommand` 的參數，流程圖會處理一次後捨棄，或在每個音訊畫面中處理。

4. 遊戲負責更新每個音訊畫面的內容資料，方法是使用 `ACP_COMMAND_UPDATE_*_CONTEXT` 命令，或是將更新與流程圖處理正確同步並手動更新內容。

   * [ACP\_COMMAND\_UPDATE\_DMA\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_dma_context)
   * [ACP\_COMMAND\_UPDATE\_EQCOMP\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_eqcomp_context)
   * [ACP\_COMMAND\_UPDATE\_FILTVOL\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_filtvol_context)
   * [ACP\_COMMAND\_UPDATE\_PCM\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_pcm_context)
   * [ACP\_COMMAND\_UPDATE\_SRC\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_src_context)
   * [ACP\_COMMAND\_UPDATE\_XMA\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_xma_context)

   更新內容時，請注意 [SubmitCommand](/zh-TW/reference/audio/acphal/interfaces/IAcpHal/methods/iacphal_submitcommand) 的旗標參數會決定更新是盡快進行，還是在下一個音訊畫面進行。

如需手動同步內容更新之方法的詳細資訊，請參閱 [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/zh-TW/reference/audio/acphal/structs/acp_command_load_shape_flowgraph) 命令。一般而言，請使用 `ACP_COMMAND_TYPE_UPDATE_*_CONTEXT` 命令在每個音訊畫面更新少量內容。使用這些命令更新大量內容並不有效率，因為除了處理命令之外，還必須將大量內容資料複製並傳輸至 ACP。如果您要更新大量內容，遊戲應修改內容資料，然後將非持續性流程圖提交至 ACP，或善用 `ACP_COMMAND_TYPE_START_FLOWGRAPH` 命令以及 [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/zh-TW/reference/audio/acphal/structs/acp_command_load_shape_flowgraph) 命令的 `waitForStart` 參數，以暫緩處理直到內容更新完成。當流程圖完成處理後，即可再次更新內容。

更新內容的第三種替代方式是使用雙重緩衝處理。遊戲可以在處理流程圖時更新內容的第二份複本，並在音訊畫面開始時交換內容。

<a id="ID4EHF" />

#### 流程圖剖析

ACP 會在音訊畫面結束時終止持續性流程圖的剖析，此音訊畫面是有 2.667 毫秒限制的 ACP 音訊畫面。如果遊戲的流程圖需要音訊畫面 75% 的時間來處理，但遊戲直到音訊畫面進行到 30% 時才讓處理開始，則流程圖中未剖析的部分就會被清除。流程圖本身不會被變更。發生這種情況時，如果遊戲已註冊接收訊息，ACP 就會傳送 `ACP_MESSAGE_TYPE_FLOWGRAPH_TERMINATED` 訊息。若要判斷哪些命令未插入內部 SHAPE 佇列，遊戲可以檢查流程圖命令的 `queued` 旗標。

無論提交時間為何，非持續性流程圖通常都會處理至完成。例外情況之一是由於來源資料無法使用或 `disabled` 旗標使用不當，而導致一或多個命令被封鎖。遊戲可以在 ACP 音訊畫面期間的任何時間點提交非持續性流程圖，並可確定 (少數邊界情況除外) 它會完成。好處是，只要遊戲仍在 2.667 毫秒的 ACP 音訊畫面間隔內處理流程圖，就不必與音訊時鐘完全同步。風險是，如果遊戲未穩定地提交流程圖，或流程圖需要超過 2.667 毫秒，就可能導致音訊中斷。

以下是流程圖存留期的摘要。

* 持續性流程圖會在 ACP 上保持作用中，直到提交新的流程圖或 null 流程圖 (實際上會將其移除) 將其取代為止。

* 除非用戶端指示 ACP 等待開始命令，否則 ACP 會在音訊畫面開始時開始處理持續性流程圖。

* ACP 會在音訊畫面結束前不久停止處理持續性流程圖，即使尚未完全處理完畢。

* 非持續性流程圖只會在完成前保持作用中，完成後即被移除。

* 非持續性流程圖會在音訊畫面之間保持作用中。只有在完成後才會被移除。

<Note>命令處理與流程圖剖析無關。ACP 會持續掃描新命令，並在剖析流程圖或執行其他工作時盡快處理這些命令。</Note>

<a id="ID4EHG" />

#### 更新流程圖

更新流程圖的選項與先前所述更新內容的選項類似。基本規則相同：請勿在處理流程圖時更新流程圖。

您可以使用三種策略來更新流程圖。

1. 使用非持續性流程圖，視需要重建，並在音訊畫面開始時提交。遊戲可以視需要多次重複使用相同的流程圖。如果流程圖沒有變更，遊戲就不需要重建。您也可以在處理舊流程圖時建構新流程圖，以雙重緩衝此方法。重建時，不僅可以從頭建構流程圖，還可以透過適當設定混音緩衝區識別碼，視需要儲存和連結流程圖的各個區段。

2. 使用持續性流程圖，並只在需要變更時重建和取代。雙重緩衝在此也適用。藉由不使用 [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/zh-TW/reference/audio/acphal/structs/acp_command_load_shape_flowgraph) 的 `waitForStart` 參數，可以讓 ACP 自由執行。ACP 會在音訊畫面開始時，並在處理完標記為該音訊畫面的命令後，立即開始處理流程圖。或者，可以設定 `waitForStart` 參數，以防止在傳送 `ACP_COMMAND_TYPE_START_FLOWGRAPH` 命令之前處理流程圖。這不會直接影響流程圖更新，但可稍微改善同步。

3. 在流程圖命令上使用 `disabled` 旗標來停用流程圖的部分內容。例如，可以建置一個主流程圖，但每次執行只啟用所需的區段。這必須與選項 1 或 2 搭配使用，才能將新的流程圖傳送至 ACP。請注意，ACP 目前不會周遊流程圖來尋找孤立的區塊。遊戲必須停用流程圖中的完整路徑 (而不只是第一個節點)。如果未這麼做，SHAPE 命令會暫時使硬體停滯。這些停滯可能很單純，例如單一無法處理的區塊以少量成本被移除；也可能嚴重到使整個語音停滯。

對於語音數量龐大或每個音訊畫面進行大量更新的遊戲，請使用雙重緩衝技術。

如果遊戲使用 `ACP_MESSAGE_TYPE_FLOWGRAPH_COMPLETED` 來管理更新，則在 ACP 將訊息新增至訊息佇列到遊戲呼叫 `PopMessage` 之間，ACP 可能會閒置很長一段時間。請勿使用此方法管理更新，請讓 ACP 保持運作。

<a id="ID4ELH" />

#### 多個流程圖

如果多個流程圖的合計需求不超過硬體功能，遊戲可以在每個音訊畫面處理多個流程圖。好處是遊戲可以執行多個音訊引擎 (包括中介軟體和自訂引擎)，或將剖析拆分為更容易管理的區塊。缺點是 SHAPE 硬體在此模式下的執行效率會較低。若要達到 SHAPE 的最大輸送量，每個 SHAPE 區塊都必須保持 100% 忙碌，而在處理多個流程圖時是不可能做到的。

每個 ACP 用戶端只能載入一個流程圖。如果用戶端提交新的流程圖，就會取代現有的流程圖。需要支援多個流程圖的遊戲，必須為每種流程圖類型建立個別的用戶端 (每個用戶端都有自己的命令和訊息佇列)，或必須等待流程圖完成後再提交新的流程圖。

多個流程圖的支援是設計給多個用戶端使用，而不是單一用戶端。這讓中介軟體引擎可以提交其流程圖，而遊戲則可提交個別的流程圖進行額外的自訂處理。請為遊戲所需的每個 ACP 用戶端建立 `IACPHAL` 介面的執行個體。

由於所有 ACP 和 SHAPE 資源 (尤其是內容陣列) 由所有用戶端共用，因此用戶端必須協調這些資源的配置和共用。

<a id="ID4EZH" />

### DMA 公用程式

包含 *ShapeDMAContext.h* 檔案中的直接記憶體存取 (DMA) 公用程式。下列公用程式會在 [SHAPE\_DMA\_CONTEXT](/zh-TW/reference/audio/shapedmacontext/structs/shape_dma_context) 結構上運作。如需詳細資訊，請參閱 [ShapeDmaContext (DMA 公用程式方法)](/zh-TW/reference/audio/shapedmacontext/shapedmacontext_members)。

<a id="ID4EIAAC" />

### EQ 壓縮器公用程式

包含 *ShapeEqCompContext.h* 檔案中的 EQCOMP 公用程式。這些公用程式會在 [SHAPE\_EQCOMP\_CONTEXT](/zh-TW/reference/audio/shapeeqcompcontext/structs/shape_eqcomp_context) 結構上運作。

如需詳細資訊，請參閱 [ShapeEqCompContext (EQCOMP 公用程式方法)](/zh-TW/reference/audio/shapeeqcompcontext/shapeeqcompcontext_members)。

<a id="ID4EWAAC" />

### 濾波器音量公用程式

包含 *ShapeFiltVolContext.h* 檔案中的濾波器音量公用程式。這些公用程式會在 [SHAPE\_FILTVOL\_CONTEXT](/zh-TW/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context) 結構上運作。

如需詳細資訊，請參閱 [ShapeFiltVolContext (FLTVOL 公用程式方法)](/zh-TW/reference/audio/shapefiltvolcontext/shapefiltvolcontext_members)。

<a id="ID4EEBAC" />

### PCM 公用程式

包含 *ShapePCMContext.h* 檔案中的脈衝編碼調變 (PCM) 公用程式。這些公用程式會在 [SHAPE\_PCM\_CONTEXT](/zh-TW/reference/audio/shapepcmcontext/structs/shape_pcm_context) 結構上運作。

如需詳細資訊，請參閱 [ShapePcmContext (PCM 公用程式方法)](/zh-TW/reference/audio/shapepcmcontext/shapepcmcontext_members)。

<a id="ID4ESBAC" />

### SRC 公用程式

包含 *ShapeSRCContext.h* 檔案中的取樣率轉換器 (SRC) 公用程式。這些公用程式會在 [SHAPE\_SRC\_CONTEXT](/zh-TW/reference/audio/shapesrccontext/structs/shape_src_context) 結構上運作。

如需詳細資訊，請參閱 [ShapeSrcContext (SRC 公用程式方法)](/zh-TW/reference/audio/shapesrccontext/shapesrccontext_members)。

<a id="ID4EACAC" />

### XMA 公用程式

包含 *ShapeXMAContext.h* 檔案中的 XMA 公用程式。這些公用程式會在 [SHAPE\_XMA\_CONTEXT](/zh-TW/reference/audio/shapexmacontext/structs/shape_xma_context) 結構上運作。

如需詳細資訊，請參閱 [ShapeXmaContext (XMA 公用程式方法)](/zh-TW/reference/audio/shapexmacontext/shapexmacontext_members)。

硬體模擬的 XMA 解碼功能有限。如需詳細資訊，請參閱 [SHAPE\_XMA\_CONTEXT](/zh-TW/reference/audio/shapexmacontext/structs/shape_xma_context) 結構主題。

遊戲可以在不使用流程圖的情況下使用 XMA 資料，但資料仍必須透過 ACP，使用下表所示的 [ACP\_COMMAND\_TYPE](/zh-TW/reference/audio/acphal/enums/acp_command_type) 命令。

| 命令 | 描述 |
| - | - |
| `ACP_COMMAND_TYPE_ENABLE_XMA_CONTEXT` | 啟用單一 XMA 內容，ACP 會開始解碼內容中指定的緩衝區。 |
| `ACP_COMMAND_TYPE_ENABLE_XMA_CONTEXTS` | 啟用一組 XMA 內容，ACP 會開始解碼內容中定義的緩衝區。 |
| `ACP_COMMAND_TYPE_DISABLE_XMA_CONTEXT` | 停用單一 XMA 內容，ACP 會停止解碼內容中指定的緩衝區。 |
| `ACP_COMMAND_TYPE_DISABLE_XMA_CONTEXTS` | 停用一組 XMA 內容，ACP 會停止解碼內容中定義的緩衝區。 |
| `ACP_COMMAND_TYPE_UPDATE_XMA_CONTEXT` | 更新 XMA 內容中的一或多個欄位。這可以在 ACP 上同步進行，也可以非同步進行。 |

使用這些命令，遊戲可以依照下列作業順序，以幾乎與使用 XBOX 360 XMA HAL 相同的方式使用 XBOX One ACP HAL。

1. 以相關資料填入一或多個內容：緩衝區、位移等。

2. 啟用內容。

3. 更新內容。如果內容已停用，遊戲可以直接修改其內容。如果內容已啟用，遊戲可以先將其停用，或使用 `ACP_COMMAND_TYPE_UPDATE_XMA_CONTEXT` 命令，後者可能更有效率，因為 ACP 會處理停用、等待和更新。

一般而言，遊戲不應只使用 SHAPE 的 XMA 元件。建立只需少量維護的「前端」流程圖幾乎輕而易舉，而且能讓遊戲免費獲得高品質的 SRC 及其他功能。流程圖易於建立和管理，並可將 SRC 從主要 CPU 卸載，同時提升品質。

<a id="ID4EXEAC" />

### 目標值

公用程式函式中可設定的目標值，代表參數在音訊畫面結束時的最終值。例如，[SHAPE\_FILTVOL\_CONTEXT](/zh-TW/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context) 結構包含 `gain` 和 `gainTarget` 的值。在處理畫面時，`gain` 會使用線性內插和下列方程式計算。

```cpp theme={null}
gain = ((gainTarget - gain) / 127) * i + gain  
```

其中 i 從 0 到 127。

在畫面結束時，`gain` 將等於 `gainTarget`。

可以為 ACP 設定目標參數，如下表所示。

| 元件 | 目標 | 描述 |
| - | - | - |
| EQCOMP | `eqAB0Target` | EQ A b0 係數目標 |
| EQCOMP | `eqAB1Target_L` | EQ A b1 係數目標，低 8 位元 |
| EQCOMP | `eqAB1Target_H` | EQ A b1 係數目標，高 16 位元 |
| EQCOMP | `eqAB2Target_L` | EQ A b2 係數目標，低 16 位元 |
| EQCOMP | `eqAB2Target_H` | EQ A b2 係數目標，高 8 位元 |
| EQCOMP | `eqAA1Target` | EQ A a1 係數目標 |
| EQCOMP | `eqAA2Target` | EQ A a2 係數目標 |
| EQCOMP | `eqBB0Target_L` | EQ B b0 係數目標，低 8 位元 |
| EQCOMP | `eqBB0Target_H` | EQ B b0 係數目標，高 16 位元 |
| EQCOMP | `eqBB1Target_L` | EQ B b1 係數目標，低 16 位元 |
| EQCOMP | `eqBB1Target_H` | EQ B b1 係數目標，高 8 位元 |
| EQCOMP | `eqBB2Target` | EQ B b2 係數目標 |
| EQCOMP | `eqBA1Target` | EQ B a1 係數目標 |
| EQCOMP | `eqBA2Target_L` | EQ B a2 係數目標，低 8 位元 |
| EQCOMP | `eqBA2Target_H` | EQ B a2 係數目標，高 16 位元 |
| EQCOMP | `eqCB0Target_L` | EQ C b0 係數目標，低 16 位元 |
| EQCOMP | `eqCB0Target_H` | EQ C b0 係數目標，高 8 位元 |
| EQCOMP | `eqCB1Target` | EQ C b1 係數目標 |
| EQCOMP | `eqCB2Target` | EQ C b2 係數目標 |
| EQCOMP | `eqCA1Target_L` | EQ C a1 係數目標，低 8 位元 |
| EQCOMP | `eqCA1Target_H` | EQ C a1 係數目標，高 16 位元 |
| EQCOMP | `eqCA2Target_L` | EQ C a2 係數目標，低 16 位元 |
| EQCOMP | `eqCA2Target_H` | EQ C a2 係數目標，高 8 位元 |
| EQCOMP | `compGainTarget` | 使用者可設定的輸出增益目標 |
| FILTVOL | `gainTarget` | 音量目標層級 |
| FILTVOL | `qRecipTarget` | 目標 1/Q 值 |
| FILTVOL | `fcTarget` | 目標頻率值 |
| SRC | `samplingIncrementTarget` | 取樣遞增的結束值 |

<a id="ID4E3NAC" />

### 執行緒安全

[IACPHAL 介面方法](/zh-TW/reference/audio/acphal/interfaces/IAcpHal/iacphal)和 [ACPHAL 方法](/zh-TW/reference/audio/acphal/acphal_members)是安全執行緒。如果呼叫了 [ApuCreateHeap](/zh-TW/reference/audio/apu/functions/apucreateheap)，該堆積會由所有執行緒使用。

下列公用程式函式*不是*安全執行緒。不過，我們提供了這些函式的原始程式碼。如有必要，您可以讓它們成為安全執行緒。一般的做法是使用[關鍵區段物件](https://msdn.microsoft.com/library/windows/desktop/ms682530\(v=vs.85\).aspx)。

* [ShapeFlowGraph (流程圖)](/zh-TW/reference/audio/shapeflowgraph/shapeflowgraph_members)
* [ShapeDmaContext (DMA)](/zh-TW/reference/audio/shapedmacontext/shapedmacontext_members)
* [ShapeEqCompContext (EQCOMP)](/zh-TW/reference/audio/shapeeqcompcontext/shapeeqcompcontext_members)
* [ShapeFiltVolContext (FLTVOL)](/zh-TW/reference/audio/shapefiltvolcontext/shapefiltvolcontext_members)
* [ShapePcmContext (PCM)](/zh-TW/reference/audio/shapepcmcontext/shapepcmcontext_members)
* [ShapeSrcContext (SRC)](/zh-TW/reference/audio/shapesrccontext/shapesrccontext_members)
* [ShapeXmaContext (XMA)](/zh-TW/reference/audio/shapexmacontext/shapexmacontext_members)

<a id="ID4EUPAC" />

### 針對 PCM 和 XMA 資料使用 SRC 的指導方針

下表顯示將 SRC 區塊與 PCM 和 XMA 資料搭配使用的指導方針。

| 目標 | 實作 |
| - | - |
| 非迴圈線性 PCM | 對 SRC 使用 `SHAPE_SRC_COMMAND_TYPE_START` 啟動語音。讓語音播放至結尾。您也可以選擇使用 `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` 在結尾前停止。 |
| 無限迴圈線性 PCM | 將 PCM 內容迴圈計數 (`loopCount`) 設定為 `SHAPE_PCM_INFINITE_LOOP_COUNT`。對 SRC 使用 `SHAPE_SRC_COMMAND_TYPE_START` 啟動語音。零。讓語音播放，直到您想在迴圈結尾停止時發出 `SHAPE_SRC_COMMAND_TYPE_STOP_END`，並讓語音播放完畢。您也可以選擇發出 `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` 立即停止。 |
| 有限迴圈線性 PCM | 將 PCM 內容迴圈計數 (`loopCount`) 設定為 \[0, 254]。對 SRC 使用 `SHAPE_SRC_COMMAND_TYPE_START` 啟動語音。讓語音播放至結尾。您也可以選擇使用 `SHAPE_SRC_COMMAND_TYPE_STOP_END` 在迴圈結尾停止，並讓語音播放完畢。您也可以選擇發出 `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` 立即停止。 |
| 循環 PCM | 對 SRC 使用 `SHAPE_SRC_COMMAND_TYPE_START` 啟動語音。持續串流資料並更新 PCM 內容寫入指標，直到您想停止為止。發出 `SHAPE_SRC_COMMAND_TYPE_STOP_END`，讓 SRC 播放至目前的 PCM 寫入指標 (`loopStartWritePointer`)。您也可以選擇發出 `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` 立即停止。 |
| 串流 (非硬體迴圈) XMA | 對 SRC 使用 `SHAPE_SRC_COMMAND_TYPE_START` 啟動語音。當最後一個 XMA 輸入緩衝區用盡時，發出 `SHAPE_SRC_COMMAND_TYPE_STOP_END` 以播放至已解碼緩衝區的結尾 (請參閱下方的「附註」)。您也可以選擇發出 `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` 立即停止。 |
| 無限硬體迴圈 XMA | 將 XMA 內容迴圈計數 (`numLoops`) 設定為 `SHAPE_XMA_INFINITE_LOOP_COUNT`。對 SRC 使用 `SHAPE_SRC_COMMAND_TYPE_START` 啟動語音。讓語音播放，直到您想在迴圈結尾停止時，將 XMA 迴圈計數設定為零並發出 `SHAPE_SRC_COMMAND_TYPE_STOP_END`，然後讓語音播放完畢。您也可以選擇發出 `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` 立即停止。 |
| 有限硬體迴圈 XMA | 將 XMA 內容迴圈計數 (`numLoops`) 設定為 \[0, 254]。對 SRC 使用 `SHAPE_SRC_COMMAND_TYPE_START` 啟動語音。讓語音播放，並監看迴圈計數，直到您想在迴圈結束時停止。當計數為零時，發出 `SHAPE_SRC_COMMAND_TYPE_STOP_END` 並讓語音播放完畢。若要在下一個迴圈結尾停止，您也可以選擇將迴圈計數設定為零。當最後一個 XMA 輸入緩衝區用盡時，將 SRC 命令設定為 `SHAPE_SRC_COMMAND_TYPE_STOP_END` 並讓語音播放完畢 (請參閱下方的「附註」)。若要立即停止，請發出 `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`。 |

<Note>完成上述任一情境後，SRC 命令會是 `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`。</Note>

請以處理 SHAPE 流程圖的相同頻率檢查 XMA 輸入緩衝區的有效位元。如果您將此檢查作為串流邏輯的一部分 (其執行間隔長得多)，XMA 輸出緩衝區可能會在您指示 SRC 於結尾停止之前就已清空。這可能會導致流程圖停滯。

<a id="ID4E5BAE" />

### 暫停和繼續遊戲

遊戲必須能夠暫停和繼續，例如當使用者將其置於受限模式時。使用 `IAcpHal` 直接針對 SHAPE 硬體撰寫程式碼時，若要暫停和繼續，只需讓遊戲停止提交命令即可。已提交的命令會正常完成，並可能填滿訊息佇列。

如果遊戲使用持續性流程圖，應載入 null 流程圖以停止處理。這與使用 `XAudio2` 撰寫程式碼時的暫停和繼續程序不同。如需詳細資訊，請參閱 [XAudio2 概觀](/zh-TW/build/console-features/audio/overviews/xaudio2-overview)。

## 參考 API 文件

* [Acphal (API 內容)](/zh-TW/reference/audio/acphal/acphal_members)
  * 結構
    * [ACP\_COMMAND\_UPDATE\_DMA\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_dma_context)
    * [ACP\_COMMAND\_UPDATE\_EQCOMP\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_eqcomp_context)
    * [ACP\_COMMAND\_UPDATE\_FILTVOL\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_filtvol_context)
    * [ACP\_COMMAND\_UPDATE\_PCM\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_pcm_context)
    * [ACP\_COMMAND\_UPDATE\_SRC\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_src_context)
    * [ACP\_COMMAND\_UPDATE\_XMA\_CONTEXT](/zh-TW/reference/audio/acphal/structs/acp_command_update_xma_context)
    * [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/zh-TW/reference/audio/acphal/structs/acp_command_load_shape_flowgraph)
* [Shapedmacontext (API 內容)](/zh-TW/reference/audio/shapedmacontext/shapedmacontext_members)
  * 結構
    * [SHAPE\_DMA\_CONTEXT](/zh-TW/reference/audio/shapedmacontext/structs/shape_dma_context)
* [Shapeeqcompcontext (API 內容)](/zh-TW/reference/audio/shapeeqcompcontext/shapeeqcompcontext_members)
  * 結構
    * [SHAPE\_EQCOMP\_CONTEXT](/zh-TW/reference/audio/shapeeqcompcontext/structs/shape_eqcomp_context)
* [Shapefiltvolcontext (API 內容)](/zh-TW/reference/audio/shapefiltvolcontext/shapefiltvolcontext_members)
  * 結構
    * [SHAPE\_FILTVOL\_CONTEXT](/zh-TW/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context)
* [Shapeflowgraph (API 內容)](/zh-TW/reference/audio/shapeflowgraph/shapeflowgraph_members)
* [Shapepcmcontext (API 內容)](/zh-TW/reference/audio/shapepcmcontext/shapepcmcontext_members)
  * 結構
    * [SHAPE\_PCM\_CONTEXT](/zh-TW/reference/audio/shapepcmcontext/structs/shape_pcm_context)
* [Shapesrccontext (API 內容)](/zh-TW/reference/audio/shapesrccontext/shapesrccontext_members)
  * 結構
    * [SHAPE\_SRC\_CONTEXT](/zh-TW/reference/audio/shapesrccontext/structs/shape_src_context)
* [Shapexmacontext (API 內容)](/zh-TW/reference/audio/shapexmacontext/shapexmacontext_members)
  * 結構
    * [SHAPE\_XMA\_CONTEXT](/zh-TW/reference/audio/shapexmacontext/structs/shape_xma_context)
* [apu (API 內容)](/zh-TW/reference/audio/apu/apu_members)
  * 函式
    * [ApuCreateHeap](/zh-TW/reference/audio/apu/functions/apucreateheap)


## Related topics

- [服務 C API 概觀 - PFLocalization.h](/zh-TW/services/playfab/api-references/c/pflocalization/pflocalization_members.md)
- [服務 C API 概觀 - PFStatistics.h](/zh-TW/services/playfab/api-references/c/pfstatistics/pfstatistics_members.md)
- [服務 C API 概觀 - PFLeaderboards.h](/zh-TW/services/playfab/api-references/c/pfleaderboards/pfleaderboards_members.md)
- [服務 C API 概觀 - PFPlatformSpecific.h](/zh-TW/services/playfab/api-references/c/pfplatformspecific/pfplatformspecific_members.md)
- [服務 C API 概觀 - PFStatisticsTypes.h](/zh-TW/services/playfab/api-references/c/pfstatisticstypes/pfstatisticstypes_members.md)
