Procédure : Créer un XAPO

L’API XAPO fournit l’interface IXAPO et la classe CXAPOBase pour créer de nouveaux types XAPO. L’interface IXAPO contient toutes les méthodes qui doivent être implémentées pour créer un XAPO. La classe CXAPOBase fournit une implémentation de base de l’interface IXAPO . CXAPOBase implémente toutes les méthodes d’interface IXAPO , à l’exception de la méthode IXAPO::P rocess , qui est unique à chaque XAPO.

Pour créer un XAPO statique

  1. Dérivez une nouvelle classe XAPO de la classe de base CXAPOBase .

    Notes

    XAPOs implémentent l’interface IUnknown . Les interfaces IXAPO et IXAPOParameters incluent les trois méthodes IUnknown : QueryInterface, AddRef et Release. CXAPOBase fournit des implémentations des trois méthodes IUnknown . Une nouvelle instance de CXAPOBase aura un nombre de références de 1. Il sera détruit lorsque son nombre de références deviendra 0. Pour permettre à XAudio2 de détruire un instance d’un XAPO lorsqu’il n’est plus nécessaire, appelez IUnknown::Release sur le XAPO une fois qu’il a été ajouté à une chaîne d’effets XAudio2. Consultez Guide pratique pour utiliser un XAPO dans XAudio2 pour plus d’informations sur l’utilisation d’un XAPO avec XAudio2.

     

  2. Remplacez l’implémentation de la classe CXAPOBase de la méthode IXAPO::LockForProcess .

    La substitution de LockForProcess permet de stocker des informations sur le format des données audio pour les utiliser dans IXAPO::P rocess.

  3. Implémentez la méthode IXAPO::P rocess .

    XAudio2 appelle la méthode IXAPO::P rocess chaque fois qu’un XAPO doit traiter des données audio. Le processus contient l’essentiel du code d’un XAPO.

Implémentation de la méthode Process

La méthode IXAPO::P rocess accepte les mémoires tampons de flux pour les données audio d’entrée et de sortie. Un XAPO classique attend une mémoire tampon de flux d’entrée et une mémoire tampon de flux de sortie. Vous devez baser le traitement des données de la mémoire tampon de flux d’entrée sur le format spécifié dans la fonction LockForProcess et tous les indicateurs passés à la fonction Process avec la mémoire tampon de flux d’entrée. Copiez les données de mémoire tampon de flux d’entrée traitées dans la mémoire tampon du flux de sortie. Définissez le paramètre BufferFlags de la mémoire tampon du flux de sortie comme XAPO_BUFFER_VALID ou XAPO_BUFFER_SILENT.

L’exemple suivant illustre une implémentation LockForProcess et Process qui copie simplement les données d’une mémoire tampon d’entrée vers une mémoire tampon de sortie. Toutefois, il n’y a pas de traitement si la mémoire tampon d’entrée est marquée avec 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

}

Lors de l’écriture d’une méthode Process , il est important de noter que les données audio XAudio2 sont entrelacées. Cela signifie que les données de chaque canal sont adjacentes pour un numéro d’exemple particulier. Par exemple, si une onde à 4 canaux est lue dans une voix source XAudio2, les données audio sont un exemple de canal 0, un exemple de canal 1, un exemple de canal 2, un exemple de canal 3, puis l’exemple suivant de canaux 0, 1, 2, 3, et ainsi de suite.

Effets audio

Vue d’ensemble de XAPO