次の方法で共有


方法 : XAPO の作成

XAPO API には、新しい XAPO タイプの作成に使用できる IXAPO インターフェイスと CXAPOBase クラスが用意されています。IXAPO インターフェイスには、新しい XAPO を作成するために実装する必要のあるすべてのメソッドが含まれます。CXAPOBase クラスは、IXAPO インターフェイスの基本的な実装を提供します。CXAPOBase は、各 XAPO に固有の IXAPO::Process メソッドを除き、IXAPO インターフェイスのすべてのメソッドを実装します。

新しい静的 XAPO を作成するには

  1. CXAPOBase 基本クラスから新しい XAPO クラスを派生させます。

        XAPO で IUnknown インターフェイスが実装されます。IXAPO および IXAPOParameters インターフェイスには、3 つのIUnknown メソッド (QueryInterfaceAddRef、および Release) があります。CXAPOBase は、3 つのすべての IUnknown メソッドの実装を提供します。CXAPOBase の新しいインスタンスのリファレンスカウントは 1 になります。それが 0 になるとインスタンスは破棄されます。XAPO インスタンスが不要になった場合に XAudio2 でそれを破棄するには、XAPO を XAudio2 エフェクト チェーンに追加した後に、IUnknown::Release を呼び出します。XAPO を XAudio2 と共に使用する方法の詳細については、「方法 : XAudio2 での XAPO の使用」を参照してください。

  2. CXAPOBase クラスの IXAPO::LockForProcess メソッドの実装をオーバーライドします。

    LockForProcess をオーバーライドすると、オーディオ データの形式に関する情報を、IXAPO::Process で使用できるように格納できます。

  3. IXAPO::Process メソッドを実装します。

    XAPO でオーディオ データの処理が必要な場合は常に、XAudio2 から IXAPO::Process メソッドが呼び出されます。Process には、XAPO に使用されるコードの大部分が格納されます。

Process メソッドの実装

IXAPO::Process メソッドは、入出力オーディオ データのストリーム バッファーを受け入れます。一般的な XAPO では、入力ストリーム バッファーと出力ストリーム バッファーがそれぞれ 1 つずつであると予測されます。入力ストリーム バッファーから受け取るデータは、LockForProcess 関数で指定された形式、および入力ストリーム バッファーと共に Process 関数に渡されたフラグに基づいて処理される必要があります。処理された入力ストリーム バッファーのデータは、出力ストリーム バッファーにコピーします。出力ストリーム バッファーの BufferFlags パラメーターは、XAPO_BUFFER_VALID または XAPO_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

}

関連トピック