UWP AudioGraph:垃圾收集器导致音频输出中的点击

时间:2019-02-08 18:32:30

标签: c# audio uwp

我有一个使用AudioGraph API的C#UWP应用程序。

我在glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);上使用了自定义效果。

我遵循了此页面上的示例: https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/custom-audio-effects

它可以工作,但是自定义效果运行时,我每秒可以听到扬声器中的多次咔嗒声。

这是我的MediaSourceAudioInputNode方法的代码:

ProcessFrame

我使用了Visual Studio探查器来确定问题的原因。 显然存在内存问题。垃圾收集每秒运行几次。在每个垃圾收集中,我都能听到咔嗒声。

Visual Studio分析器显示垃圾收集对象的类型为 public unsafe void ProcessFrame(ProcessAudioFrameContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } AudioFrame frame = context.InputFrame; using (AudioBuffer inputBuffer = frame.LockBuffer(AudioBufferAccessMode.Read)) using (IMemoryBufferReference inputReference = inputBuffer.CreateReference()) { ((IMemoryBufferByteAccess)inputReference).GetBuffer(out byte* inputDataInBytes, out uint inputCapacity); Span<float> samples = new Span<float>(inputDataInBytes, (int)inputCapacity / sizeof(float)); for (int i = 0; i < samples.Length; i++) { float sample = samples[i]; // sample processing... samples[i] = sample; } } }

这些对象是在进入ProcessAudioFrameContext方法之前由AudioGraph API创建的,并作为参数传递给该方法。

有什么办法可以避免这些频繁的垃圾收集?

2 个答案:

答案 0 :(得分:2)

该问题并非特定于自定义效果,而是AudioGraph的一个普遍问题(当前SDK为1809)。 垃圾回收可能会使AudioGraph线程暂停太长时间(超过10毫秒,这是音频缓冲区的默认大小)。结果是可以在音频输出中听到喀哒声。 自定义效果的使用给垃圾收集器带来很大压力。

我找到了一个好的解决方法。它使用GC.TryStartNoGCRegion方法。

调用此方法后,单击完全消失。但是应用程序会一直在内存中增长,直到调用GC.EndNoGCRegion方法为止。

// at the beginning of playback...
// 240 Mb is the amount of memory that can be allocated before a GC occurs
GC.TryStartNoGCRegion(240 * 1024 * 1024, true);

// ... at the end of playback
GC.EndNoGCRegion();

MSDN文档: https://docs.microsoft.com/fr-fr/dotnet/api/system.gc.trystartnogcregion?view=netframework-4.7.2

一篇好文章: https://mattwarren.org/2016/08/16/Preventing-dotNET-Garbage-Collections-with-the-TryStartNoGCRegion-API/

答案 1 :(得分:0)

垃圾收集器可能会对您做出反应,每帧初始化样本临时内存,然后在帧之后释放该临时内存,尝试在启动代码中分配用于保存样本的内存,然后每帧重用它。