首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Javasound中播放多个示例

在Javasound中播放多个示例
EN

Stack Overflow用户
提问于 2017-02-20 11:25:46
回答 1查看 50关注 0票数 0

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

我有多个示例(每个MIDI音调一个),它们作为一个(全局访问的) Map<MidiPitch,AudioInputStream>加载到内存中。

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

如果该事件为便笺,则获取一个剪辑并按以下方式播放:

代码语言:javascript
复制
Clip clip = AudioSystem.getClip();
clip.open(lookupAIS(pitch));
clip.start();

然后将该剪辑添加到一个全局可访问的Map<MidiPitch,List<Clip>>中,表示已启动的剪辑,即已按上述方式调用start()但尚未收到备注事件的剪辑。

如果事件是备注,则从上面的地图中获得相应的已启动剪辑列表。删除列表顶部的剪辑,并在其中调用stop()close()

上面的Receiver以通常的方式连接到MidiSystem.getSequencer(),然后调用:

代码语言:javascript
复制
sequencer.setSequence(MidiSystem.getSequence(new File(myMidFile)))
sequencer.open()
sequencer.start()

Thread.sleep(aLongTime())

sequencer.stop()
sequencer.close()

当驱动MIDI序列的速度较慢时,上述方法可以工作,但在较高的节奏下,只需挂起音符(即使对于包含极少量音符的序列也是如此)。

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

有人能告诉我为什么会发生这种事吗?这可能是一个同步问题吗?

编辑:所谓“挂起”,我的意思是有些笔记被卡住了,尽管日志输出报告了相应的‘停止’方法已经被调用了。

EDIT2:好像是在第二次播放给定的音符时第一次出现挂起的情况。即使MIDI序列是单音的,即先前的音符已经停止,也会发生这种情况。

EN

回答 1

Stack Overflow用户

发布于 2017-02-20 21:18:59

您为每次播放加载剪辑的方法将是可变延迟的相当大的来源。每次调用该文件时,都会重新读取该文件,直到整个文件完成加载后才会开始播放。

我建议预装所有剪辑并将它们保存在内存中。调用便笺时,将剪辑光标设置为零,然后播放:

代码语言:javascript
复制
clip[mapIndex].setFramePosition(0);
clip[mapIndex].start();

这些剪辑应该已经打开了。我将它们放在一个数组中,并使用"mapIndex“作为一种合理的方法来选择正确的剪辑,该剪辑可能与您已经设置的映射一起工作。

您可能不需要“停止”或“关闭”剪辑,直到整个序列已经完成,除非剪辑是相当长的,并被设计为在过程中停止,或如果他们是作为循环播放。

这将大大改善情况。我不知道它是否能解决所有问题。cpu可能正在执行一些线程复用,在当前代码中,在剪辑完成对另一个线程的加载之前,偶尔会在一个线程上调用clip.close。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42343297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档