如何消除DirectShow筛选器链中的1秒延迟?(使用Delphi和DSPACK)
我有一个Delphi 6 Pro应用程序,它使用DSPACK组件库从系统首选的音频输入设备向Skype发送音频。我正在使用TSampleGrabber组件点击过滤图链,然后将音频缓冲区发送到Skype。问题是我每秒只收到一次音频。换句话说,TsSampleGrabber实例的OnBuffer()事件每秒只触发一次,Buffer参数中有一整秒钟的数据。我需要知道如何修改过滤图链,以便它以比每秒一次更快的间隔从输入设备获取数据。如果可能的话,我希望每50毫秒或至少每100毫秒做一次 我的过滤图链由一个映射到顶部系统首选音频输入设备的TFilter组成。我将该过滤器的输出管脚连接到指定TFilter的“WAV Dest”输入管脚,以便以PCM WAV格式获取样本。然后,我将“WAV Dest”过滤器的输出管脚连接到TSampleGrabber实例的输入管脚。要以更快的间隔触发TSampleGrabber OnBuffer()事件,我需要做哪些更改如何消除DirectShow筛选器链中的1秒延迟?(使用Delphi和DSPACK),delphi,audio,directshow,dspack,Delphi,Audio,Directshow,Dspack,我有一个Delphi 6 Pro应用程序,它使用DSPACK组件库从系统首选的音频输入设备向Skype发送音频。我正在使用TSampleGrabber组件点击过滤图链,然后将音频缓冲区发送到Skype。问题是我每秒只收到一次音频。换句话说,TsSampleGrabber实例的OnBuffer()事件每秒只触发一次,Buffer参数中有一整秒钟的数据。我需要知道如何修改过滤图链,以便它以比每秒一次更快的间隔从输入设备获取数据。如果可能的话,我希望每50毫秒或至少每100毫秒做一次 我的过滤图链由一
更新:根据Roman R的回答,我能够实现我在下面展示的解决方案。一个音符。他的链接让我看到了以下对解决方案很有帮助的博客文章:
我想您需要微调音频捕获过滤器,以在缓冲区中捕获您想要的大小,即足够短以使总延迟变小 音频捕获过滤器在输出管脚上公开
iambufference
接口,并且SuggestAllocatorProperties
允许您指定缓冲区配置
有关更多信息,请参阅:。谢谢@Roman R。我已更新了我的原始帖子,加入了我在您的原始链接后找到的解决方案。
// 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;