我有一个使用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创建的,并作为参数传递给该方法。
有什么办法可以避免这些频繁的垃圾收集?
答案 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
答案 1 :(得分:0)
垃圾收集器可能会对您做出反应,每帧初始化样本临时内存,然后在帧之后释放该临时内存,尝试在启动代码中分配用于保存样本的内存,然后每帧重用它。