實作 IMediaObject::AllocateStreamingResources

[與此頁面相關聯的功能Windows 媒體播放機 SDK是舊版功能。 它已被 MediaPlayer 取代MediaPlayer已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用MediaPlayer,而不是Windows 媒體播放機 SDK。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]

在 Echo 範例中, AllocateStreamingResources 方法會建立延遲緩衝區。 它會執行下列動作來執行此動作:

  1. 計算對應于指定媒體類型之指定延遲時間之緩衝區的大小。
  2. 配置新的記憶體,或在緩衝區大小已經存在時重新配置。
  3. 呼叫方法,以代表無聲的值填滿緩衝區。

無聲的值會根據位深度而有所不同。 若為 8 位音訊,無聲會以十六進位值 80 表示;對於 16 位音訊,無聲會以零表示。

計算延遲緩衝區大小

若要計算延遲緩衝區所需的大小,您必須先擷取包含音訊資料相關資訊的 一個包含 AUDIOATEX 結構。 下列範例會從輸入 DMO_MEDIA_TYPE 結構擷取這個結構的指標:

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

一旦您將指標儲存到適當的 一個顯示型態, 就可以檢查其成員,並使用它們來計算所需的緩衝區大小。 下列程式碼範例將示範下列情況:

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

此演算法會計算緩衝區大小,方法是將延遲時間乘以毫秒、以毫秒為單位的樣本數目,然後將結果乘以通道數目,然後將結果乘以每個樣本的位元組數目。 每個樣本的通道數目和位元組數目並不明顯;它們會在 nBlockAlign 成員中編碼。 除以 1000,會將 nSamplesPerSec 值減少為每毫秒樣本數;毫秒是所需的單位,因為延遲時間是以毫碼錶示。

配置延遲緩衝區記憶體

計算記憶體需求之後,您就可以配置緩衝區。 如果緩衝區存在,可能需要刪除緩衝區,例如當使用者叫用屬性頁來變更延遲時間值時。 下列程式碼示範如何配置延遲緩衝區:

// 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;

如果已成功配置緩衝區,您應該將可移動指標移至緩衝區的前端,如下列範例所示:

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

以無聲填滿延遲緩衝區

撰寫方法以表示無聲的值填入延遲緩衝區是很方便的。 方法應該會接收有效之一次的一個顯示型態的 POINTERATEX 結構,然後檢查 wBitsPerSample 成員,以判斷音訊是否為 8 位或更高版本。 下列範例會以正確的無聲值填入延遲緩衝區:

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

請記得將函式的正向宣告新增至私用區段中的標頭檔 Echo.h:

void FillBufferWithSilence(WAVEFORMATEX *pWfex);

您應該在 AllocateStreamingResources 結尾新增程式碼,以在每次建立或調整延遲緩衝區時呼叫此方法。 下列範例程式碼會將名為 pWave 的WAVEATEX 指標傳遞至新的方法:

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

重新配置延遲緩衝區記憶體

當使用者使用屬性頁變更延遲時間時,延遲緩衝區的大小也必須變更。 您已將程式碼新增至 AllocateStreamingResources 以調整緩衝區的大小,但您需要將一行程式碼新增至 CEcho::p ut_delay,以在每次屬性值變更時呼叫資源配置方法。 程式碼如下:

// Reallocate the delay buffer.
AllocateStreamingResources();

使用串流資源