共用方式為


使用方法:建立 XAPO

XAPO API 提供 IXAPO 介面和 CXAPOBase 類別,以建置新的 XAPO 類型。 IXAPO介面包含所有需要實作以建立新 XAPO 的方法。 CXAPOBase類別提供IXAPO介面的基本實作。 CXAPOBase 會實作所有 IXAPO 介面方法,但 IXAPO::P rocess 方法除外,每個 XAPO 都是唯一的。

若要建立新的靜態 XAPO

  1. CXAPOBase 基類衍生新的 XAPO 類別。

    注意

    XAPOs 會實作 IUnknown 介面。 IXAPOIXAPOParameters介面包含三個 IUnknown方法:QueryInterfaceAddRefReleaseCXAPOBase 提供所有三個 IUnknown 方法的實作。 CXAPOBase的新實例會有 1 個參考計數。 當其參考計數變成 0 時,將會終結。 若要在不再需要 XAPO 時允許 XAudio2 終結 XAPO 的實例,請在將 IUnknown::Release 新增至 XAudio2 效果鏈結之後,于 XAPO 上呼叫 IUnknown::Release 。 如需搭配 XAudio2 使用 XAPO 的詳細資訊,請參閱如何:在 XAudio2 中使用 XAPO

     

  2. 覆寫IXAPO::LockForProcess方法的CXAPOBase類別實作。

    覆寫 LockForProcess 允許儲存音訊資料格式的相關資訊,以用於 IXAPO::P rocess

  3. 實作 IXAPO::P rocess 方法。

    每當 XAPO 需要處理音訊資料時,XAudio2 會呼叫 IXAPO::P rocess 方法。 進程 包含 XAPO 的大量程式碼。

實作 Process 方法

IXAPO::P rocess方法接受輸入和輸出音訊資料的資料流程緩衝區。 典型的 XAPO 預期會有一個輸入資料流程緩衝區和一個輸出資料流程緩衝區。 您應該根據 LockForProcess 函式中指定的格式,以及使用輸入資料流程緩衝區傳遞至 Process 函式的任何旗標,從輸入資料流程緩衝區處理資料。 將已處理的輸入資料流程緩衝區資料複製到輸出資料流程緩衝區。 將輸出資料流程緩衝區的 BufferFlags 參數設定為 XAPO_BUFFER_VALIDXAPO_BUFFER_SILENT

下列範例示範 LockForProcessProcess 實作,該實作只會將資料從輸入緩衝區複製到輸出緩衝區。 不過,如果輸入緩衝區標記為 XAPO_BUFFER_SILENT,則不會有任何處理。

STDMETHOD(LockForProcess) (UINT32 InputLockedParameterCount,
          const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pInputLockedParameters,
          UINT32 OutputLockedParameterCount,
          const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pOutputLockedParameters)
{
    assert(!IsLocked());
    assert(InputLockedParameterCount == 1);
    assert(OutputLockedParameterCount == 1);
    assert(pInputLockedParameters != NULL);
    assert(pOutputLockedParameters != NULL);
    assert(pInputLockedParameters[0].pFormat != NULL);
    assert(pOutputLockedParameters[0].pFormat != NULL);


    m_uChannels = pInputLockedParameters[0].pFormat->nChannels;
    m_uBytesPerSample = (pInputLockedParameters[0].pFormat->wBitsPerSample >> 3);

    return CXAPOBase::LockForProcess(
        InputLockedParameterCount,
        pInputLockedParameters,
        OutputLockedParameterCount,
        pOutputLockedParameters);
}
STDMETHOD_(void, Process)(UINT32 InputProcessParameterCount,
           const XAPO_PROCESS_BUFFER_PARAMETERS* pInputProcessParameters,
           UINT32 OutputProcessParameterCount,
           XAPO_PROCESS_BUFFER_PARAMETERS* pOutputProcessParameters,
           BOOL IsEnabled)
{
    assert(IsLocked());
    assert(InputProcessParameterCount == 1);
    assert(OutputProcessParameterCount == 1);
    assert(NULL != pInputProcessParameters);
    assert(NULL != pOutputProcessParameters);


    XAPO_BUFFER_FLAGS inFlags = pInputProcessParameters[0].BufferFlags;
    XAPO_BUFFER_FLAGS outFlags = pOutputProcessParameters[0].BufferFlags;

    // assert buffer flags are legitimate
    assert(inFlags == XAPO_BUFFER_VALID || inFlags == XAPO_BUFFER_SILENT);
    assert(outFlags == XAPO_BUFFER_VALID || outFlags == XAPO_BUFFER_SILENT);

    // check input APO_BUFFER_FLAGS
    switch (inFlags)
    {
    case XAPO_BUFFER_VALID:
        {
            void* pvSrc = pInputProcessParameters[0].pBuffer;
            assert(pvSrc != NULL);

            void* pvDst = pOutputProcessParameters[0].pBuffer;
            assert(pvDst != NULL);

            memcpy(pvDst,pvSrc,pInputProcessParameters[0].ValidFrameCount * m_uChannels * m_uBytesPerSample);
            break;
        }

    case XAPO_BUFFER_SILENT:
        {
            // All that needs to be done for this case is setting the
            // output buffer flag to XAPO_BUFFER_SILENT which is done below.
            break;
        }

    }

    // set destination valid frame count, and buffer flags
    pOutputProcessParameters[0].ValidFrameCount = pInputProcessParameters[0].ValidFrameCount; // set destination frame count same as source
    pOutputProcessParameters[0].BufferFlags     = pInputProcessParameters[0].BufferFlags;     // set destination buffer flags same as source

}

撰寫 Process 方法時,請務必注意 XAudio2 音訊資料交錯。 這表示每個通道的資料都與特定樣本編號相鄰。 例如,如果有 4 通道波浪播放 XAudio2 來源語音,音訊資料是通道 0 的範例、通道 1 的範例、通道 2 的範例、通道 3 的樣本,然後是下一個通道 0、1、2、3 等的樣本。

音訊效果

XAPO 概觀