在Javasound中播放多个示例

在Javasound中播放多个示例,java,audio,midi,javasound,Java,Audio,Midi,Javasound,我想用Javasound编写一个简单的MIDI驱动的音频序列器 我有多个样本(每个MIDI音高一个样本)作为(全局可访问的)Map加载到内存中 javax.sound.midi.Receiver的自定义子类对传入的midi事件作出如下响应: Clip clip = AudioSystem.getClip(); clip.open(lookupAIS(pitch)); clip.start(); 如果事件是一个注释,则获得一个剪辑并按如下方式播放: Clip clip = AudioSystem

我想用Javasound编写一个简单的MIDI驱动的音频序列器

我有多个样本(每个MIDI音高一个样本)作为(全局可访问的)
Map
加载到内存中

javax.sound.midi.Receiver的自定义子类对传入的midi事件作出如下响应:

Clip clip = AudioSystem.getClip();
clip.open(lookupAIS(pitch));
clip.start();
如果事件是一个注释,则获得一个剪辑并按如下方式播放:

Clip clip = AudioSystem.getClip();
clip.open(lookupAIS(pitch));
clip.start();
然后将片段添加到全局可访问的
映射
,表示已启动的片段,即如上所述已调用
start()
但尚未收到注释事件的片段

如果事件是注释,则从上面的贴图中获得相应的已启动剪辑列表。列表开头的剪辑将被删除,并对其调用
stop()
close()

上面的
接收器
以常规方式连接到
MidiSystem.getSequencer()
,然后调用以下命令:

sequencer.setSequence(MidiSystem.getSequence(new File(myMidFile)))
sequencer.open()
sequencer.start()

Thread.sleep(aLongTime())

sequencer.stop()
sequencer.close()
当驱动MIDI序列的节奏较慢时,上述方法有效,但在更高的节奏下,音符会简单地挂起(即使是包含非常少量音符的序列)

我的理解是,
clip.start()
由Javasound API在幕后单独的线程中运行

有人能提出为什么会发生这种情况吗?这可能是一个同步问题吗

编辑:所谓“挂起”,我的意思是一些注释被卡住了,尽管日志输出报告相应的“停止”方法已被调用


EDIT2:当一个给定的音符被第二次演奏时,看起来好像是第一次挂起。即使MIDI序列是单声道的,也会发生这种情况,即上一个音符已停止

您为每场比赛加载剪辑的方法将是可变延迟的一个重要来源。每次调用此函数时,都会重新读取该文件,直到整个文件加载完毕后才会开始播放

我建议预先加载所有剪辑并将其保存在内存中。调用“打开备忘”时,将剪辑光标设置为零,然后播放:

clip[mapIndex].setFramePosition(0);
clip[mapIndex].start();
这些剪辑应该已经打开了。我将它们放在一个数组中,并使用“mapIndex”作为一种合理的方法来选择正确的剪辑,该剪辑可能适用于您已经设置的映射

在整个序列完成之前,您可能不需要“停止”或“关闭”剪辑,除非剪辑相当长,并且设计为在播放过程中停止,或者它们作为循环播放


这将大大改善情况。我不能说它是否能解决所有问题。cpu可能正在执行一些线程多路复用,在当前代码中,有时可能会在一个线程上调用clip.close,而在另一个线程上加载完该片段之前。

挂起是否意味着某些片段会继续播放?你能证明(例如,日志)你的代码确实试图阻止那个剪辑吗?@CL在上面澄清。我们不想玩猜谜游戏,只需发布你所有的代码,你在每个步骤中所做的都是未知的-理论上一切都是有效的