Menerapkan IMediaObject::AllocateStreamingResources

[Fitur yang terkait dengan halaman ini, Pemutar Media Windows SDK, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer. MediaPlayer telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer alih-alih Pemutar Media Windows SDK, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]

Dalam sampel Echo, metode AllocateStreamingResources membuat buffer penundaan. Ini dilakukan dengan melakukan hal berikut:

  1. Menghitung ukuran untuk buffer yang sesuai dengan waktu penundaan yang ditentukan untuk jenis media tertentu.
  2. Mengalokasikan memori baru atau merealokasi ukuran buffer jika sudah ada.
  3. Memanggil metode yang mengisi buffer dengan nilai yang mewakili keheningan.

Nilai untuk keheningan berbeda tergantung pada kedalaman bit. Untuk audio 8-bit, keheningan diwakili oleh nilai hex 80; untuk audio 16-bit, keheningan diwakili oleh nol.

Menghitung Ukuran Buffer Tunda

Untuk menghitung ukuran yang diperlukan untuk buffer penundaan, Anda harus terlebih dahulu mengambil struktur WAVEFORMATEX yang berisi informasi tentang data audio. Contoh berikut mengambil pointer ke struktur ini dari struktur DMO_MEDIA_TYPE input:

// Get a pointer to the WAVEFORMATEX structure.
WAVEFORMATEX *pWave = ( WAVEFORMATEX * ) m_mtInput.pbFormat;
if (NULL == pWave)
{
    return E_FAIL;
}

Setelah Anda menyimpan pointer ke struktur WAVEFORMATEX yang tepat, Anda dapat memeriksa anggotanya dan menggunakannya untuk menghitung ukuran buffer yang diperlukan. Contoh kode berikut menunjukkan hal ini:

// Get the size of the buffer required.
m_cbDelayBuffer = (m_dwDelayTime * pWave->nSamplesPerSec * pWave->nBlockAlign) / 1000;

Algoritma ini menghitung ukuran buffer dengan mengalikan waktu penundaan, dalam milidetik, dengan jumlah sampel per milidetik, lalu mengalikan hasilnya dengan jumlah saluran, lalu mengalikan hasilnya dengan jumlah byte per sampel. Jumlah saluran dan jumlah byte per sampel tidak jelas; mereka dikodekan dalam anggota nBlockAlign. Pembagian sebesar 1000 mengurangi nilai nSamplesPerSec menjadi sampel per milidetik; milidetik adalah unit yang diinginkan karena waktu penundaan dinyatakan dalam milidetik.

Mengalokasikan Tunda Memori Buffer

Setelah menghitung persyaratan memori, Anda dapat mengalokasikan buffer. Buffer mungkin perlu dihapus jika ada, seperti ketika pengguna memanggil halaman properti untuk mengubah nilai waktu penundaan. Kode berikut menunjukkan pengalokasian buffer penundaan:

// Test whether a buffer exists.
if (m_pbDelayBuffer)
{
    // A buffer already exists.
    // Delete the delay buffer.
    delete m_pbDelayBuffer;
    m_pbDelayBuffer = NULL;
}

// Allocate the buffer.
m_pbDelayBuffer = new BYTE[m_cbDelayBuffer];

if (!m_pbDelayBuffer)
    return E_OUTOFMEMORY;

Jika buffer berhasil dialokasikan, Anda harus memindahkan penunjuk bergerak ke kepala buffer, seperti yang ditunjukkan dalam contoh berikut:

// Move the echo pointer to the head of the delay buffer.
m_pbDelayPointer = m_pbDelayBuffer;

Mengisi Buffer Penundaan dengan Keheningan

Lebih mudah untuk menulis metode untuk mengisi buffer penundaan dengan nilai yang mewakili keheningan. Metode harus menerima penunjuk ke struktur WAVEFORMATEX yang valid dan kemudian memeriksa anggota wBitsPerSample untuk menentukan apakah audio 8-bit atau lebih tinggi. Contoh berikut mengisi buffer penundaan dengan nilai yang benar untuk keheningan:

void CEcho::FillBufferWithSilence(WAVEFORMATEX *pWfex)
{
    if (8 == pWfex->wBitsPerSample)
    {
    ::FillMemory(m_pbDelayBuffer, m_cbDelayBuffer, 0x80);
    }
    else
    ::ZeroMemory(m_pbDelayBuffer, m_cbDelayBuffer);
}

Ingatlah untuk menambahkan deklarasi penerusan untuk fungsi ke file header Echo.h di bagian privat:

void FillBufferWithSilence(WAVEFORMATEX *pWfex);

Anda harus menambahkan kode di akhir AllocateStreamingResources untuk memanggil metode ini setiap kali buffer penundaan dibuat atau diubah ukurannya. Contoh kode berikut meneruskan pointer WAVEFORMATEX bernama pWave ke metode baru:

// Fill the buffer with values representing silence.
FillBufferWithSilence(pWave);

Merealokasi Memori Buffer Penundaan

Ketika pengguna mengubah waktu penundaan dengan menggunakan halaman properti, ukuran buffer penundaan juga harus berubah. Anda telah menambahkan kode ke AllocateStreamingResources untuk mengubah ukuran buffer, tetapi Anda perlu menambahkan baris kode ke CEcho::p ut_delay untuk memanggil metode alokasi sumber daya setiap kali nilai properti berubah. Berikut adalah kodenya:

// Reallocate the delay buffer.
AllocateStreamingResources();

Bekerja dengan Sumber Daya Streaming