Bagikan melalui


Cara: Membuat XAPO

XAPO API menyediakan antarmukaIXAPOdan kelasCXAPOBaseuntuk 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 metodeIXAPO::P rocess, yang unik untuk setiap XAPO.

Untuk membuat XAPO statis baru

  1. Dapatkan kelas XAPO baru dari kelas dasarCXAPOBase.

    Nota

    XAPOs mengimplementasikan antarmuka IUnknown. Antarmuka IXAPO dan IXAPOParameters mencakup tiga metode IUnknown: QueryInterface, AddRef, dan Release. CXAPOBase menyediakan implementasi dari ketiga metode IUnknown secara lengkap. 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 kelasCXAPOBase dari metodeIXAPO::LockForProcess.

    Mengambil alih LockForProcess memungkinkan informasi tentang format data audio untuk disimpan untuk digunakan dalam IXAPO::Process.

  3. Terapkan metode IXAPO::Process.

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

Menerapkan Metode Proses

Metode IXAPO::Process 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 Process 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 LockForProcess dan implementasi Proses 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 dicatat bahwa data audio XAudio2 diselingi. Ini berarti data dari setiap saluran berdekatan untuk nomor sampel tertentu. Misalnya, jika ada gelombang dengan 4 saluran yang dimasukkan ke dalam suara sumber XAudio2, data audio tersebut terdiri dari sampel saluran 0, sampel saluran 1, sampel saluran 2, sampel saluran 3, dan kemudian sampel berikutnya dari saluran 0, 1, 2, 3, dan seterusnya.

Efek Audio

Gambaran Umum XAPO