2011-10-24 31 views
5

我有使用DSPACK組件庫從系統的優選的音頻輸入設備的音頻發送到Skype的一個Delphi 6臨應用程序。我正在使用一個TSampleGrabber組件來進入Filter Graph鏈,然後將音頻緩衝區發送到Skype。問題是我每秒只能聽音頻一次。換句話說,對於TSampleGrabber實例OnBuffer()事件只能觸發一次用一整秒的價值的數據緩衝區中的參數的第二。我需要知道如何修改我的Filter Graph鏈,以便以比每秒一次更快的間隔從輸入設備抓取數據。如果可能的話,我希望每50ms或至少每100ms快一點。如何消除DirectShow過濾器鏈中的1秒延遲? (使用Delphi和DSPACK)

我的篩選器圖形鏈由被在頂部映射到系統的優選的音頻輸入裝置的TFilter的。我將該濾波器的輸出引腳連接到'WAV Dest'分配的TFilter的輸入引腳,以便我可以以PCM WAV格式獲取樣本。然後,將'WAV Dest'濾波器的輸出引腳連接到TSampleGrabber實例的輸入引腳。我需要改變什麼才能讓TSampleGrabber OnBuffer()事件以更快的間隔觸發?


UPDATE:基於羅馬的r回答我能實現,我下面展示的解決方案。一個音符。他的鏈接導致我下面的博客文章,在解決方案是有幫助的:

http://sid6581.wordpress.com/2006/10/09/minimizing-audio-capture-latency-in-directshow/

// Variable declaration for output pin to manipulate. 
var 
    intfCapturePin: IPin; 

............... 


    // Put this code after you have initialized your audio capture device 
    // TFilter instance *and* set it's wave audio format. My variable for 
    // this is FFiltAudCap. I believe you need to set the buffer size before 
    // connecting up the pins of the Filters. The media type was 
    // retrieved earlier (theMediaType) when I initialized the audio 
    // input device Filter so you will need to do similarly. 

    // Get a reference to the desired output pin for the audio capture device. 
    with FFiltAudCap as IBaseFilter do 
     CheckDSError(findPin(StringToOleStr('Capture'), intfCapturePin)); 

    if not Assigned(intfCapturePin) then 
     raise Exception.Create('Unable to find the audio input device''s Capture output pin.'); 

    // Set the capture device buffer to 50 ms worth of audio data to 
    // reduce latency. NOTE: This will fail if the device does not 
    // support the latency you desire so make sure you watch out for that. 
    setBufferLatency(intfCapturePin as IAMBufferNegotiation, 50, theMediaType); 

.................. 

// The setBufferLatency() procedure. 
procedure setBufferLatency(
       // A buffer negotiation interface pointer. 
       intfBufNegotiate: IAMBufferNegotiation; 
       // The desired latency in milliseconds. 
       bufLatencyMS: WORD; 
       // The media type the audio stream is set to. 
       theMediaType: TMediaType); 
var 
    allocProp: _AllocatorProperties; 
    wfex: TWaveFormatEx; 
begin 
    if not Assigned(intfBufNegotiate) then 
     raise Exception.Create('The buffer negotiation interface object is unassigned.'); 

    // Calculate the number of bytes per second using the wave 
    // format belonging to the given Media Type. 
    wfex := getWaveFormat(theMediaType); 

    if wfex.nAvgBytesPerSec = 0 then 
     raise Exception.Create('The average bytes per second value for the given Media Type is 0.'); 

    allocProp.cbAlign := -1; // -1 means "no preference". 
    // Calculate the size of the buffer needed to get the desired 
    // latency in milliseconds given the average bytes per second 
    // of the Media Type's audio format. 
    allocProp.cbBuffer := Trunc(wfex.nAvgBytesPerSec * (bufLatencyMS/1000)); 
    allocProp.cbPrefix := -1; 
    allocProp.cBuffers := -1; 

    // Try to set the buffer size to the desired. 
    CheckDSError(intfBufNegotiate.SuggestAllocatorProperties(allocProp)); 
end; 

回答

6

我想你需要微調音頻捕獲過濾器在你想要的大小的緩衝區來捕捉,足即短使整體延遲較小。

音頻捕獲過濾器暴露在輸出引腳IAMBufferNegotiation接口和SuggestAllocatorProperties允許您指定緩衝區的配置。

詳情參見:Configuring Windows Media Audio Encoder DMO to reduce delay

+0

感謝@Roman R.我已經更新了我原來的職位,包括我發現下面原來的鏈接的解決方案。 –