2011-10-24 27 views
5

私は、システムの優先オーディオ入力デバイスからSkypeにオーディオを送るためにDSPACKコンポーネントライブラリを使用するDelphi 6 Proアプリを持っています。 TSampleGrabberコンポーネントを使用してフィルタグラフチェーンをタップし、オーディオバッファをSkypeに送信します。問題は、私は1秒に1度だけオーディオを取得していることです。言い換えると、TSampleGrabberインスタンスのOnBuffer()イベントは、1秒に1回、Bufferパラメータの2秒分のデータだけで起動します。フィルター・グラフ・チェーンを変更する方法を知る必要があるため、入力装置からのデータを1秒に1回よりも速い間隔で取得します。可能であれば、私は50msごとに、または少なくとも100msごとにそれをやりたいと思います。どのようにDirectShowのフィルタチェーンの1秒の遅延を排除するには? (DelphiとDSPACKの使用)

私のフィルタグラフチェーンは、最上位のシステムの優先オーディオ入力デバイスにマップされたTFilterで構成されています。私はそのフィルタの出力ピンを 'WAV Dest'のTFilterに割り当てられた入力ピンに接続して、サンプルをPCM WAVフォーマットで得ることができます。次に、「WAV Dest」フィルタの出力ピンをTSampleGrabberインスタンスの入力ピンに接続します。 TSampleGrabber OnBuffer()イベントをより速い間隔で発生させるためには、何を変更する必要がありますか?


UPDATE:ローマンRの答えに基づいて、私は以下を示す午前ソリューションを実装することができました。 1つのメモ。彼のリンクは、溶液中で役に立った次のブログ記事に私を導いた:

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.元のリンクに続いて見つかった解決策を含めるためにオリジナルの投稿を更新しました。 –

関連する問題