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

# 使用 XDSP API 進行單一串流 FFT/IFFT 概觀

> 使用 XDSP API 進行單一串流 FFT/IFFT 概觀

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

## 硬體連線和啟動

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

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

2. *baseBufferLength* - *baseBuffer* 的長度 (以位元組為單位)。此緩衝區應至少為 64KB。

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

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

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

```cpp theme={null}
class TransformOneBufferManager 
{ 
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](/zh-TW/reference/audio/xdspaudio/structs/xdspactivationparameters) 中指定 [XDspProcessType](/zh-TW/reference/audio/xdspaudio/enums/xdspprocesstype)、區塊框架計數、聲道計數、以浮點數為單位的脈衝回應長度，以及指向頻域中脈衝回應資料的指標。只允許單聲道或立體聲串流。對於 [XDspProcessType::ForwardFourierTransform](/zh-TW/reference/audio/xdspaudio/enums/xdspprocesstype) 和 [XDspProcessType::inverseFourierTransform](/zh-TW/reference/audio/xdspaudio/enums/xdspprocesstype)，[XDspActivationParameters::impulseResponse](/zh-TW/reference/audio/xdspaudio/structs/xdspactivationparameters) 應為 nullptr，且 [XDspActivationParameters::impulseResponseLengthInFloats](/zh-TW/reference/audio/xdspaudio/structs/xdspactivationparameters) = 0。應適當地設定 [XDspActivationOptions](/zh-TW/reference/audio/xdspaudio/enums/xdspactivationoptions)。

以下是啟用一個正向傅立葉轉換串流的程式碼，反向傅立葉轉換的程式碼也類似。

```cpp theme={null}
XDspActivationParameters params; 
XDspStatus* status; 
XDspStreamHandle* streamHandle; 
params.type = isForward ? XDspProcessType::ForwardFourierTransform : XDspProcessType::InverseFourierTransform;  // choose FFT vs IFFT
params.blockFrameCount = maxBufferFrameCount; 
params.channelCount = 1; // only mono is supported 
params.impulseResponseLengthInFloats = 0; // should be 0 for FFT/IFFT
params.impulseResponse = nullptr;  // should be nullptr for FFT/IFFT
params.options |= isPolar ? XDspActivationOptions::EnablePolarFormat : XDspActivationOptions::None;  // specifies whether the output should be in Polar format or Cartesian format and for IFFT this specifies whether the input is in Polar or Cartesian format.
 
hr = XDspActivate(clientHandle, &params, &status, &streamHandle);
```

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

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

```cpp theme={null}
XDspCommand command;  
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](/zh-TW/reference/audio/xdspaudio/structs/xdspstatus)，以尋找提交至硬體之命令的狀態：

```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](/zh-TW/reference/audio/xdspaudio/structs/xdspstatus) 結果中傳回錯誤時，應呼叫 [XDspDeactivate](/zh-TW/reference/audio/xdspaudio/functions/xdspdeactivate)。

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

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

## 終止

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

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


## Related topics

- [使用 XDSP API 进行单流 FFT/IFFT 概述](/zh-CN/build/console-features/audio/overviews/xdsp-overview-single-stream-fft-ifft.md)
- [XDSP API を使用したシングル ストリーム FFT/IFFT の概要](/ja-jp/build/console-features/audio/overviews/xdsp-overview-single-stream-fft-ifft.md)
- [Overview of a single stream FFT/IFFT using the XDSP API](/build/console-features/audio/overviews/xdsp-overview-single-stream-fft-ifft.md)
- [XDSP API를 사용한 싱글 스트림 FFT/IFFT 개요](/ko/build/console-features/audio/overviews/xdsp-overview-single-stream-fft-ifft.md)
- [Información general de una FFT/IFFT de secuencia única mediante la API XDSP](/es/build/console-features/audio/overviews/xdsp-overview-single-stream-fft-ifft.md)
