为Java程序中添加播放MIDI音乐功能
Java在多媒体处理方面并没有太大的优势,但是有时候我们需要一些音乐作为程序中的点缀。如果播放的音乐是wav等波形音频文件,那就相当大了,所以背景音乐是MIDI。但是很多播放MIDI的在线教程都是简单的单词的例子,没有考虑到资源的释放。如果程序长时间运行,内存消耗会越来越多,以至于最后会抛出一个java.lang.OutOfMemoryError。
在MIDI播放中,有一个类比较重要,就是MidiSystem类,负责整个MIDI播放设备的管理,等等。其实就是Sequencer,是一个播放MIDI序列的MIDI播放设置,还有一类是Seqence,是MIDI序列。MIDI序列可以由程序本身生成,也可以从文件或URL中读取。
让我们来看一个例子:
/*
* test 5 . Java
*
*创建于2007-9-22,11:16:22
*
*若要更改此模板,请选择“工具”|“模板”
*并在编辑器中打开该模板。
*/
包test1
导入Java . io . file;
导入Java . io . io exception;
导入Java . io . inputstream;
导入Java . util . hashtable;
导入Java . util . map;
导入Java . util . logging . level;
导入Java . util . logging . logger;
import javax . sound . midi . invalidmidiataexception;
导入javax . sound . midi . midi system;
import javax . sound . midi . midiunavailableexception;
导入javax . sound . midi . sequence;
导入javax . sound . midi . sequencer;
/* *
*
* @ author hadeslee
*/
公共类Test5实现Runnable{
私人音序器midi
private String[]names = { " 1 . mid "," 2.mid "," 3.mid "," 4.mid "," 5 . mid " };
private int I;
私图地图;
public test 5(){
init map();
新线程(this)。start();
}
private void init map(){
try {
map = new Hashtable();
midi = midi system . get sequencer(false);
midi . open();
for(String s:names){
try {
Sequence S1 = midi system . get Sequence(新文件);
map.put(s,S1);
} catch(InvalidMidiDataException ex){
logger . get logger(test 5 . class . getname())。日志(级别。严重,空,例如);
} catch(io exception ex){
logger . get logger(test 5 . class . getname())。日志(级别。严重,空,例如);
}
}
} catch(MidiUnavailableException ex){
logger . get logger(test 5 . class . getname())。日志(级别。严重,空,例如);
}
}
private void create player(String name){
try {
sequence se = map . get(name);
midi . set sequence(se);
midi . start();
} catch(InvalidMidiDataException ex){
logger . get logger(test 5 . class . getname())。日志(级别。严重,空,例如);
}
}
public void run(){
while(true){
try {
system . out . println("文件已更改。"+(
String name = names[(int)(math . random()* names . length)];
create player(name);
thread . sleep(10000);
} catch(interrupted exception ex){
logger . get logger(test 5 . class . getname())。日志(级别。严重,空,例如);
}
}
}
public static void main(String[]args){
new test 5();
}
}
这里有很重要的一点,就是程序运行时,只需要一个定序器。我以前每次在程序中播放都会生成一个音序器,因为当时我想,我调用了它的close()方法。还能打开吗?其实还可以再打开,就是这样的惯性思维导致程序最终因内存溢出而崩溃。
现在按照我的播放方式,即使每10毫秒换一次MIDI,也能换上万次内存,根本不用加。呵呵,真是防不胜防。
位律师回复
0条评论