gpt4 book ai didi

delphi - 如何消除 DirectShow 过滤器链中 1 秒的延迟? (使用Delphi和DSPACK)

转载 作者:行者123 更新时间:2023-12-03 15:10:35 25 4
gpt4 key购买 nike

我有一个 Delphi 6 Pro 应用程序,它使用 DSPACK 组件库将音频从系统的首选音频输入设备发送到 Skype。我正在使用 TSampleGrabber 组件进入 Filter Graph 链,然后将音频缓冲区发送到 Skype。问题是我每秒只能收到一次音频。换句话说,TSampleGrabber 实例的 OnBuffer() 事件每秒仅触发一次,Buffer 参数中包含一整秒的数据。我需要知道如何修改我的过滤器图链,以便它以比每秒一次更快的间隔从输入设备获取数据。如果可能的话,我希望每 50 毫秒或至少每 100 毫秒执行一次。

我的过滤器图链由映射到顶部系统首选音频输入设备的 TFilter 组成。我将该滤波器的输出引脚附加到分配给 TFilter 的“WAV Dest”的输入引脚,这样我就可以获得 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 接口(interface),并且 SuggestAllocatorProperties 可让您指定缓冲区配置。

了解更多信息:Configuring Windows Media Audio Encoder DMO to reduce delay .

关于delphi - 如何消除 DirectShow 过滤器链中 1 秒的延迟? (使用Delphi和DSPACK),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7881420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com