如何消除DirectShow过滤链中的1秒延迟? (使用Delphi和DSPACK)
我有一个Delphi 6 Pro应用程序,它使用DSPACK组件库从系统的首选音频输入设备向Skype发送音频.我正在使用TSampleGrabber组件进入Filter Graph链,然后将音频缓冲区发送到Skype.问题是我每秒只能听一次音频.换句话说,TSampleGrabber实例的OnBuffer()事件仅在Buffer参数中每秒触发一次具有完整秒数的数据.我需要知道如何修改我的Filter Graph链,以便以比每秒一次更快的间隔从输入设备抓取数据.如果可能的话,我想尽快每50毫秒或至少每100毫秒做一次.
My Filter Graph链由一个TFilter组成,该TFilter映射到顶部的系统首选音频输入设备.我将该滤波器的输出引脚连接到“WAV Dest”指定TFilter的输入引脚,这样我就可以获得PCM WAV格式的采样.然后,我将’WAV Dest’滤波器的输出引脚连接到TSampleGrabber实例的输入引脚.我需要更改什么才能使TSampleGrabber OnBuffer()事件以更快的间隔触发? 更新:根据Roman 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; 解决方法
我想你需要微调音频捕获过滤器以捕获你想要的大小的缓冲区,即足够短以使整体延迟变小.
音频捕获过滤器在输出引脚上公开IAMBufferNegotiation接口,SuggestAllocatorProperties允许您指定缓冲区配置. 有关详细信息,请参阅:Configuring Windows Media Audio Encoder DMO to reduce delay. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |