c# - 什么样的定时器最适合 MIDI 定时?
问题描述
我正在用 C# 和 .NET 4.x 编写一个简单的 MIDI 应用程序供我自己使用。
我假设商业 DAW(在 Windows 平台上)使用Windows 多媒体计时器来计时 MIDI 数据的播放。但我无法验证这一点,因为商业内容是闭源的。
我希望有人在这方面有知识,并且可以告诉我我的假设是否正确。或者,这些 DAW 是否使用了我不知道的计时器?我想确保没有任何更合适的东西被我忽略了。
解决方案
虽然我没有专门为商业 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 暂停。
推荐阅读
- go - 如何从数据存储返回的对象中检索关键对象
- angular - Angular 8 到 GAE
- regex - 运行 checksetup.pl 时出错 Bugzilla 5.0.6 安装:您提供的正则表达式 '^[^,]+{' 无效
- excel - VBA Pivot Item.Name 提取错误值
- typescript - 猫鼬打字稿类
- reactjs - i18next-icu 在反应中翻译时不支持 {{ (双括号)
- javascript - 为什么我不能用字符串更新 MySQL?
- sql - 如何选择多对多关系表?
- javascript - 如何让选择选项与禁用和启用提交按钮一起使用
- vue.js - vue-table-2 的自定义搜索框