示例:如果我想在我即将推出的自制VST乐器中播放声音,并且音序器中的这个音符长度为15000个样本,并且通过processEvents将音符设置为ON,则processReplace函数开始播放声音从0到sampleFrames(在我的例子中是10000)。然后在下一次进入循环中的循环中将有5000个样本留下来播放,但是循环将从0到10000播放,这比从音符播放的样本多5000。将有5000个静音样本将被播放,这意味着此音符将在5000个样本之后关闭!?
如果序列发生器中的新声音直接放在第一个声音之后,则processReplace函数将看不到processEvents设置的短时间OFF,并将下一个样本视为第一个声音的连续声音,因为它只会看到再次输入循环时新的音符开启。
如何防止这种情况发生? 如果音符在循环中间结束,如何停止processReplace循环?
答案 0 :(得分:4)
我不确定我是否接受了你的问题,但这是对它的抨击。
当您确定从传入的Midi音符事件在processEvents中生成的声音时,下一次调用processReplace必须实现这一点。所以你需要内部状态来记住在processEvents中检测到的注释,并且需要在processReplace期间输出。
当样本的持续时间(在您的情况下)长于缓冲区可以容纳的时间(sampleFrames)时,您需要记住您正在做什么以及您在哪里。在你的例子中,已经播放了2/3的样本,下一个processReplace需要播放样本的最后1/3。
如果(Midi)音符尚未关闭(您没有收到Midi音符关闭事件),您必须决定如何处理它的VSTi插件。所以你可能想要重复那个相同的样本并在第二个processEvents调用中播放它的前三分之一 - 并记住你必须稍后播放该样本的其余部分。
如果您在此场景中的任何地方收到Midi音符关闭消息 - 您将必须存储内部状态(数据),告知插件的processReplace逻辑在播放该示例时正确停止。许多插件采用快捷方式,并将以等于processReplace缓冲区的sampleFrames的样本块处理此信息。但是如果你想要精确,你必须检查传入的Midi音符事件的deltaFrames,并在processReplace处理中考虑该偏移量。
主机(DAW)确定何时调用processEvents和processReplace方法。它通常会在插件(实例)的整个生命周期内继续这样做。因此,维护插件所处的内部状态至关重要。如果它什么都不做 - 你不会改变输出缓冲区(零输出)。
希望它有所帮助。 马克