Bagikan melalui


Cara: Membuat XAPO

API XAPO menyediakan antarmuka IXAPO dan kelas CXAPOBase untuk membangun jenis XAPO baru. Antarmuka IXAPO berisi semua metode yang perlu diimplementasikan untuk membuat XAPO baru. Kelas CXAPOBase menyediakan implementasi dasar antarmuka IXAPO . CXAPOBase mengimplementasikan semua metode antarmuka IXAPO kecuali metode IXAPO::P rocess , yang unik untuk setiap XAPO.

Untuk membuat XAPO statis baru

  1. Mendapatkan kelas XAPO baru dari kelas dasar CXAPOBase .

    Catatan

    XPO mengimplementasikan antarmuka IUnknown . Antarmuka IXAPO dan IXAPOParameters mencakup tiga metode IUnknown : QueryInterface, AddRef, dan Release. CXAPOBase menyediakan implementasi ketiga metode IUnknown . Instans baru CXAPOBase akan memiliki jumlah referensi 1. Ini akan dihancurkan ketika jumlah referensinya menjadi 0. Untuk memungkinkan XAudio2 menghancurkan instans XAPO ketika tidak lagi diperlukan, panggil IUnknown::Release pada XAPO setelah ditambahkan ke rantai efek XAudio2. Lihat Cara: Menggunakan XAPO di XAudio2 untuk informasi selengkapnya tentang menggunakan XAPO dengan XAudio2.

     

  2. Ambil alih implementasi kelas CXAPOBase dari metode IXAPO::LockForProcess .

    Mengesampingkan LockForProcess memungkinkan informasi tentang format data audio disimpan untuk digunakan dalam IXAPO::P rocess.

  3. Terapkan metode IXAPO::P rocess .

    XAudio2 memanggil metode IXAPO::P rocess setiap kali XAPO perlu memproses data audio. Proses berisi sebagian besar kode untuk XAPO.

Menerapkan Metode Proses

Metode IXAPO::P rocess menerima buffer aliran untuk data audio input dan output. XAPO yang khas akan mengharapkan satu buffer aliran input dan satu buffer aliran output. Anda harus mendasarkan pemrosesan data dari buffer aliran input pada format yang ditentukan dalam fungsi LockForProcess dan bendera apa pun yang diteruskan ke fungsi Proses dengan buffer aliran input. Salin data buffer aliran input yang diproses ke buffer aliran output. Atur parameter BufferFlags buffer aliran output sebagai XAPO_BUFFER_VALID atau XAPO_BUFFER_SILENT.

Contoh berikut menunjukkan implementasi LockForProcess dan Process yang hanya menyalin data dari buffer input ke buffer output. Namun, tidak ada pemrosesan jika buffer input ditandai dengan 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

}

Saat menulis metode Proses , penting untuk mencatat data audio XAudio2 diselingi. Ini berarti data dari setiap saluran berdekatan untuk nomor sampel tertentu. Misalnya, jika ada gelombang 4 saluran yang diputar ke dalam suara sumber XAudio2, data audio adalah sampel saluran 0, sampel saluran 1, sampel saluran 2, sampel saluran 3, dan kemudian sampel saluran berikutnya 0, 1, 2, 3, dan sebagainya.

Efek Audio

Gambaran Umum XAPO