对于我正在进行的项目,我需要暂停midi定序器,我希望所有听起来的音符都能维持,从而使这些音符无休止。我面临的问题是,sequencer.stop()
显然不仅停止播放,而且向所有发声音符发送MIDI音符关闭消息,终止所有发声音符(在一些文献中被称为flush)。
我尝试过使用sequencer.setTempoInBPM(0)
,这就完成了任务,但我的项目还有其他不必要的副作用。
最明显的解决方案似乎覆盖了Sequencer.stop()
,但我该怎么做呢?那个被覆盖的方法到底会是什么样子?
编辑:我想编辑这个问题,以回应gpasch的评论。
不仅停止播放,还向所有发音音符:你在说什么这不一样吗什么
这对于音频是正确的,但对于MIDI则不然。MIDI协议本身不指定任何音频数据。它只向乐器发出关于演奏什么的指令。该乐器解释MIDI信息并发出最终声音。
为了让乐器演奏一秒钟的声音,以下是动作:
- [Sequencer]MIDI消息输出:注意
- [乐器]MIDI信息输入:音符
- [乐器]开始解读上的音符:开始发声
- [Sequencer]等待一秒钟
- [Sequencer]MIDI消息输出:音符关闭
- [乐器]MIDI信息输入:音符关闭
- [乐器]开始解读音符关闭:停止发声
因此,如果这个过程在第4步被中断,它将产生一个"无尽的音符"。因为MIDI乐器得到了开始演奏某个音符的指令,但从未得到停止演奏该音符的指令。[*]
回顾我的问题。当我在音符中间调用sequencer.stop()
时(步骤4),而不是"无休止的音符",此时正在播放的所有尚未收到音符关闭消息的音符,请停止发声。对此的逻辑解释是,sequencer.stop()
在引擎盖下发送一条MIDI All Note Off消息。我们真的很感激,因为否则sequencer.stop()
会一团糟。在我的特殊情况下,尽管我真的需要测序仪不发送注释关闭消息。所以问题是:我能解决这个问题吗?
*如果这是一个自然衰减的钢琴声,那么这个声音最终会消亡。但对于合成音,声音将一直持续到出现
我的方法是。创建一个过滤器,它基本上会接收从测序仪发送的所有内容,并将其发送到您的midi out。在这个过滤器中创建一个条件,如果"暂停标志"为真,则所有的通知都将被接收但不会被发送。
创建一个pause()方法,当调用该方法时,首先将"暂停标志"设置为true,然后执行sequencer.stop().
当然,你需要一些方法来跟踪被屏蔽的备忘,这样你就可以在最终想要阻止它们的时候真正阻止它们,否则它们真的会永远存在。