c# - UWP AudioGraph:垃圾收集器导致音频输出中的点击
问题描述
我有一个使用 AudioGraph API 的 C# UWP 应用程序。
我在MediaSourceAudioInputNode
.
我按照此页面上的示例进行操作: https ://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/custom-audio-effects
它可以工作,但是当自定义效果运行时,我可以在扬声器中每秒听到多次点击。
这是我的ProcessFrame
方法的代码:
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;
}
}
}
我使用 Visual Studio 分析器来确定问题的原因。很明显存在内存问题。垃圾收集每秒运行几次。在每次垃圾收集时,我都能听到咔哒声。
Visual Studio 探查器显示垃圾收集的对象是 type ProcessAudioFrameContext
。
这些对象在进入方法之前由 AudioGraph API 创建ProcessFrame
并作为参数传递给方法。
我可以做些什么来避免这些频繁的垃圾收集吗?
解决方案
问题不是特定于自定义效果,而是 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
推荐阅读
- xml - 如何在 XML 中多次使用父名称?
- pine-script - 相当于 Pine Script 中的 GetValue
- excel - 如何并排显示点命名法(用逗号分隔),它们共享完全相同的数据点以防止重叠
- python - 有没有办法将此数据格式转换为 CSV?
- php - 在产品存档循环中使用自定义字段 AFC 图像字段作为背景
- nopcommerce - 如何使 Nop-Commerce 4.20 插件准备好分发
- c - c编程遇到Segmentation fault(core dumped)
- python - python递归调用会相互干扰吗?
- ruby - 如何以简单的方式重构简单的 rspec 测试以使用 subject/let/it 和 FactoryGirl?
- python - 如何在 docker 容器中使用“键盘”python 模块而不会出错?