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

# 使用 XDSP API 進行單一串流摺積概觀

> 使用 XDSP API 進行單一串流摺積概觀

在本主題中，我們將使用 Microsoft Game Development Kit (GDK) 隨附的其中一個範例，逐步說明如何在 XBOX Series X 裝置上使用硬體摺積殘響的預期程式碼流程。

## 硬體連線和啟動

必須透過 [XDspConnect](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspconnect.md) 或 [XDspConnectWithMaximumStreamLimit](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspconnectwithmaximumstreamlimit.md) 與硬體加速單元建立連線。呼叫端會使用下列參數設定連線的需求：

1. *baseBuffer* - 指向使用者配置記憶體的指標，此記憶體必須足以容納將傳遞給硬體的輸入、輸出、包絡緩衝區和/或區塊乘數緩衝區。此記憶體應透過 XMemAlloc 以下列屬性配置：*XALLOC\_MEMTYPE\_PHYSICAL\_CACHEABLE*、*XALLOC\_PAGESIZE\_64KB*、*XALLOC\_ALIGNMENT\_64K*。這些屬性應使用 `MAKE_XALLOC_ATTRIBUTES()` 設定，如下列範例所示。在 [XDspDisconnect](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspdisconnect.md) 呼叫成功之前，不應釋放此記憶體。此緩衝區的大小應至少為 64KB。

2. *baseBufferLength* - *baseBuffer* 的長度 (以位元組為單位)。此緩衝區應至少為 64KB，且不超過 500 MB。

3. *aggregateImpulseResponseInSeconds* - 代表將使用 [XDspActivate](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspactivate.md) 搭配 [XDspProcessType::Convolution](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/enums/xdspprocesstype.md) 同時啟用的所有個別脈衝回應的總持續時間。如果此值為 0，則無法啟用任何使用 [XDspProcessType::Convolution](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/enums/xdspprocesstype.md) 的串流。

4. handle - 指向 [XDspClientHandle](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/handles/xdspclienthandle.md) 的指標，用來保存此呼叫所傳回的控制代碼。

如果呼叫成功，呼叫端就可以使用 *baseBuffer*，透過 [XDspCommand](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspcommand.md) 參數傳遞輸入資料並擷取串流的輸出資料。在 [XDspCommand](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspcommand.md) 中傳遞的任何緩衝區都應以 16 位元組對齊。下列簡單緩衝區管理員範例可用於管理輸入和輸出緩衝區。

```cpp theme={null}
class ConvolveOneBufferManager
{
private:
    float const* _outputBuffer = nullptr;
    uint32_t _maxBufferFrameCount = 0;
    uint32_t _bufferStride = 0;
    uint32_t _maxBufferCount = 0;
    uint32_t _acquiredBufferCount = 0;
    uint32_t _channelCount = 1;

public:
    void Reset(float const* outputBuffer, uint32_t maxBufferCount, uint32_t maxBufferFrameCount, uint32_t channelCount) {
        _outputBuffer = outputBuffer;
        _maxBufferCount = maxBufferCount;
        _maxBufferFrameCount = maxBufferFrameCount;
        _channelCount = channelCount;
    }

    uint32_t GetMaxBufferFrameCount() const {
        return _maxBufferFrameCount;
    }

    bool IsFull() const {
        return _acquiredBufferCount >= _maxBufferCount;
    }

    void Acquire() {
        if (_acquiredBufferCount < _maxBufferCount) {
            _acquiredBufferCount++;
        }
    }

    void Release() {
        if (_acquiredBufferCount > 0) {
            _acquiredBufferCount--;
        }
    }

    float* GetOutputBuffer(uint32_t index) {
        return const_cast<float*>(_outputBuffer) + (((index % _maxBufferCount) * _maxBufferFrameCount * _channelCount));
    }

};
```

以下是配置記憶體並建立連線之第一個步驟的程式碼範例。

```cpp theme={null}
static const ULONGLONG XMemAllocAttributes = MAKE_XALLOC_ATTRIBUTES(allocatorId,
                      0,
                      XALLOC_MEMTYPE_PHYSICAL_CACHEABLE,
                      XALLOC_PAGESIZE_64KB,
                      XALLOC_ALIGNMENT_64K,
                      FALSE);

float* baseBuffer = (float *)XMemAlloc(baseBufferLength, XMemAllocAttributes);
```

其中 XMemAllocAttributes 代表上述的屬性。下列程式碼會將 *aggregateImpulseResponse* 設定為 32 秒。

```cpp theme={null}
hr = XDspConnect(baseBuffer, baseBufferLength, 32 /*aggregateImpulseResponseInSeconds*/, &clientHandle);
```

## 串流的啟用和停用

與裝置建立連線之後，呼叫端應傳送串流啟用命令以進行摺積、FFT 或 IFFT。呼叫端必須在 [XDspActivationParameters](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspactivationparameters.md) 中指定 [XDspProcessType](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/enums/xdspprocesstype.md)、區塊框架計數、聲道計數、以浮點數為單位的脈衝回應長度，以及指向頻域中脈衝回應資料的指標。只允許單聲道或立體聲串流。對於 [XDspProcessType::ForwardFourierTransform](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/enums/xdspprocesstype.md) 和 [XDspProcessType::inverseFourierTransform](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/enums/xdspprocesstype.md)，[XDspActivationParameters::impulseResponse](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspactivationparameters.md) 應為 nullptr，且 [XDspActivationParameters::impulseResponseLengthInFloats](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspactivationparameters.md) = 0。應適當地設定 [XDspActivationOptions](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/enums/xdspactivationoptions.md)。

以下是啟用一個摺積串流的程式碼。

```cpp theme={null}
XDspActivationParameters params;
XDspStatus* status;
XDspStreamHandle* streamHandle;
params.type = XDspProcessType::Convolution;
params.blockFrameCount = maxBufferFrameCount;
params.channelCount = channelCount; // mono or stereo
params.impulseResponseLengthInFloats = filterFrameCount;
params.impulseResponse = filterBuffer;

if (channelCount == 2 && deinterleaved)
{
    params.options |= XDspActivationOptions::Deinterleaved;
}
if (stereoImpulseResponse)
{
    params.options |= XDspActivationOptions::StereoImpulseResponse;
}
hr = XDspActivate(clientHandle, &params, &status, &streamHandle); 
```

[XDspActivate](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspactivate.md) 會以其中一個參數傳回 [XDspStatus](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspstatus.md) 緩衝區。此 [XDspStatus](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspstatus.md) 緩衝區應用來尋找硬體為此串流所處理之命令的狀態。收到啟用結果之後，呼叫端就可以開始提交資料以進行摺積/FFT/IFFT。這應使用 [XDspSubmitCommand](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspsubmitcommand.md) API 來完成。對於每個 [XDspSubmitCommand](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspsubmitcommand.md)，呼叫端都必須執行下列動作：

1. 以剛好 *blockFrameCount* 的資料填入輸入緩衝區。
2. 以適當的值以及 16 位元組對齊的輸入和輸出緩衝區填入 [XDspCommand](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspcommand.md)。
3. 呼叫 [XDspSubmitCommand](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspsubmitcommand.md) 將命令提交至硬體。此函式會傳回命令序號，可用來追蹤傳送至硬體的命令數目。

```cpp theme={null}
XDspCommand command;

command.beginScale = 1.0f;
command.endScale = 1.0f;
command.inputBlockBuffer = inputDataBuffer;
command.outputBlockBuffer =  bufferManager.GetOutputBuffer(_totalCommandsSubmitted + 1);
command.blockBufferMultiplier = nullptr;

uint32_t sequence = 0;
hr = XDspSubmitCommand(streamHandle, &command, &sequence);

if (SUCCEEDED(hr))
{
    totalCommandsSubmitted++;
}
```

接下來，可以依下列方式檢查 [XDspStatus](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspstatus.md)，以尋找提交至硬體之命令的狀態：

```cpp theme={null}
while (status->lastProcessedCommandSequence > totalResponsesReceived)
{
    totalResponsesReceived++;
 
    // Hardware status is only updated when there is a hardware fault and the
    // error is going to persist for the duration of the stream. But, all the
    // commands that have already been submitted will still be processed by
    // the hardware and we have to wait for these commands to be processed 
    // before calling XDspDeactivate.
    hr = status->result; 
     
    float* outBuffer = bufferManager.GetOutputBuffer(totalResponsesReceived);
    // The output will be in the outBuffer
    // Do something with the outBuffer
    bufferManager.Release();
}
```

當串流中的封包已處理完畢，或硬體在 [XDspStatus](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspstatus.md) 結果中傳回錯誤時，應呼叫 [XDspDeactivate](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspdeactivate.md)。

```cpp theme={null}
while (totalResponsesReceived < totalCommandsSubmitted)
{
    // run the above code in the while loop to obtain all the responses
}
hr = XDspDeactivate(streamHandle);
```

如果硬體尚未處理完為此串流提交的所有命令，[XDspDeactivate](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspdeactivate.md) 會傳回 *XDSP\_E\_PENDING\_RESULTS*。

## 終止

[XDspDeactivate](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspdeactivate.md) 成功之後，呼叫端必須呼叫 [XDspDisconnect](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspdisconnect.md) 以中斷與音訊硬體加速單元的連線，以釋放所有已配置的資源。如果並非所有串流都已停用，[XDspDisconnect](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspdisconnect.md) 將傳回 *XDSP\_E\_NOT\_ALL\_HANDLES\_DEACTIVATED* 錯誤。

```cpp theme={null}
hr = XDspDisconnect(clientHandle);
XMemFree(baseBuffer, XMemAllocAttributes);
```

## 參考 API 文件

* [XDspAudio (API 內容)](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/xdspaudio_members.md)
  * 函式
    * [XDspConnect](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspconnect.md)
    * [XDspConnectWithMaximumStreamLimit](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspconnectwithmaximumstreamlimit.md)
    * [XDspDisconnect](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspdisconnect.md)
    * [XDspActivate](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspactivate.md)
    * [XDspSubmitCommand](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspsubmitcommand.md)
    * [XDspDeactivate](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/functions/xdspdeactivate.md)
  * 結構
    * [XDspCommand](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspcommand.md)
    * [XDspActivationParameters](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspactivationparameters.md)
    * [XDspStatus](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/structs/xdspstatus.md)

## 另請參閱

[XDSP 概觀](https://docs.xbox.com/zh-TW/build/console-features/audio/overviews/xdsp-overview.md)


## Related topics

- [使用 XDSP API 進行含包絡的單一串流摺積](https://docs.xbox.com/zh-TW/build/console-features/audio/overviews/xdsp-overview-single-stream-convolution-with-envelope.md)
- [使用 XDSP API 進行單一串流 FFT/IFFT 概觀](https://docs.xbox.com/zh-TW/build/console-features/audio/overviews/xdsp-overview-single-stream-fft-ifft.md)
- [使用 XAPU API 進行單一串流 Opus 音訊解碼](https://docs.xbox.com/zh-TW/build/console-features/audio/overviews/xapu-overview-single-stream-audio-decode.md)
- [XDSP 包絡概觀](https://docs.xbox.com/zh-TW/build/console-features/audio/overviews/xdsp-overview-enveloping.md)
- [XDSP 音訊](https://docs.xbox.com/zh-TW/reference/audio/xdspaudio/xdspaudio_members.md)
