Dela via


Gör så här: Skapa en XAPO

XAPO-API:et tillhandahåller IXAPO--gränssnittet och CXAPOBase--klass för att skapa nya XAPO-typer. Gränssnittet IXAPO innehåller alla metoder som behöver implementeras för att skapa ett nytt XAPO. Klassen CXAPOBase tillhandahåller en grundläggande implementering av gränssnittet IXAPO. CXAPOBase implementerar alla IXAPO- gränssnittsmetoder förutom metoden IXAPO::P rocess, som är unik för varje XAPO.

Så här skapar du ett nytt statiskt XAPO

  1. Härled en ny XAPO-klass från basklassen CXAPOBase.

    Anmärkning

    XAPOs implementerar gränssnittet IUnknown. I IXAPO- och IXAPOParameters-gränssnitten ingår de tre metoderna IUnknown: QueryInterface, AddRefoch Release. CXAPOBase tillhandahåller implementeringar av alla tre metoderna IUnknown. En ny instans av CXAPOBase har referensantalet 1. Den förstörs när referensantalet blir 0. Om du vill tillåta att XAudio2 förstör en instans av en XAPO när den inte längre behövs anropar du IUnknown::Release på XAPO när den har lagts till i en XAudio2-effektkedja. Se Så här använder du en XAPO i XAudio2 för mer information om hur du använder en XAPO med XAudio2.

     

  2. Åsidosätt CXAPOBase- klassimplementering av metoden IXAPO::LockForProcess.

    Om du åsidosätter LockForProcess- kan information om formatet för ljuddata lagras för användning i IXAPO::P rocess.

  3. Implementera metoden IXAPO::P rocess.

    XAudio2 anropar IXAPO::P rocess metod när en XAPO behöver bearbeta ljuddata. Process innehåller huvuddelen av koden för en XAPO.

Implementera processmetoden

Metoden IXAPO::Process accepterar strömbuffertar för in- och utgående ljuddata. En typisk XAPO förväntar sig en indataströmbuffert och en utdataströmbuffert. Du bör basera bearbetningen av data från indataströmbufferten på det format som anges i funktionen LockForProcess och eventuella flaggor som skickas till funktionen Process med indataströmbufferten. Kopiera bearbetade indataströmsbuffertdata till utdataströmbufferten. Ange BufferFlags-parametern för utdataströmmens buffert som antingen XAPO_BUFFER_VALID eller XAPO_BUFFER_SILENT.

I följande exempel visas en LockForProcess- och Process implementering som helt enkelt kopierar data från en indatabuffert till en utdatabuffert. Det går dock inte att bearbeta om indatabufferten är markerad med 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

}

När du skriver en Process-metod är det viktigt att notera att XAudio2-ljuddata interfolieras. Det innebär att data från varje kanal ligger intill för ett visst exempelnummer. Om det till exempel spelas upp en 4-kanalsvåg i en XAudio2-källröst är ljuddata ett prov från kanal 0, ett prov från kanal 1, ett prov från kanal 2, ett prov från kanal 3 och sedan nästa prov från kanalerna 0, 1, 2, 3 och så vidare.

Ljudeffekter

XAPO-översikt