首页 > 解决方案 > 什么样的定时器最适合 MIDI 定时?

问题描述

我正在用 C# 和 .NET 4.x 编写一个简单的 MIDI 应用程序供我自己使用。

我假设商业 DAW(在 Windows 平台上)使用Windows 多媒体计时器来计时 MIDI 数据的播放。但我无法验证这一点,因为商业内容是闭源的。

我希望有人在这方面有知识,并且可以告诉我我的假设是否正确。或者,这些 DAW 是否使用了我不知道的计时器?我想确保没有任何更合适的东西被我忽略了。

标签: c#.netwinapimidi

解决方案


虽然我没有专门为商业 DAW 项目编码的特权,但我确实有为事件的准确计时很重要的场景编码的经验,包括 MIDI 处理/路由。

你的假设是正确的。编码良好的 MIDI 音序器使用 Windows 多媒体计时器来安排将 MIDI 消息发送到 MIDI 设备。

Microsoft 的Multimedia Timer Reference实际上提到了 MIDI 排序作为示例使用:

这些计时器服务对于需要高分辨率计时的应用程序很有用。例如,MIDI 音序器需要高分辨率计时器,因为它必须将 MIDI 事件的节奏保持在 1 毫秒的分辨率内。

如何使用计时器是另一个主题,我不会在这里讨论。但我想指出几点:

  • 所有现代硬件都支持 1 毫秒的计时器分辨率,这基本上是给定的,但timeGetDevCaps在调用timeBeginPeriod.

  • 使用分辨率为 1 毫秒的多媒体计时器,可以将 MIDI 信息量化为 1 毫秒网格 +/- 一些方差/抖动。在绝大多数情况下,这不是问题,因为这仍然是一个足够精细的分辨率,可以提供合理细微的时序,只要音乐时序无论如何。如果您绝对需要亚毫秒级计时,则必须按照@iinspectable 的建议进行操作-使用计时器“关闭”,然后旋转以精确计时发送 MIDI 消息。然而,这种方法是有代价的。我不知道您对应用程序的意图是什么,但是如果您同时播放多个 MIDI 轨道,每个轨道都有连续的控制器和弯音,您会发现您的应用程序一直在旋转,并且您会将 CPU 内核固定到100% 这简直太糟糕了。

  • 请查看 Windows 的多媒体类调度程序服务,以获得对 MIDI 播放线程的 CPU 资源的优先访问。

  • 不要被@iinspectable 的评论气馁。您绝对可以使用 C#/.NET 进行高性能 MIDI 排序。您唯一需要担心的是垃圾收集器会意外暂停您的应用程序。您始终可以以最小化 GC 的方式进行编码(例如,使用结构而不是类,在播放期间不要创建/销毁任何东西)。还可以考虑使用GC.TryStartNoGCRegion来防止播放期间的 GC 暂停。


推荐阅读