1.播放简单音调
最初的MIDP1.0,只能够播放简单的音调。
首先说明比较简单的Manager类播放单音。使用下面的静态方法播放单音:
static void playTone(int note, int duration, int volume);
note:播放的音调,取值为 0 ~ 127
duration:以毫秒计算的音调持续时间
volume:音量,取值为 0 ~ 100,100代表最大的音量。如果大于100, 将会被设为100.
示例代码:
for(int i = 0; i < 128; i ++){
try {
Manager.playTone(i, 1000, 100);
} catch (MediaException e) {
e.printStackTrace();
}
}
播放全部128个声调,共128秒,最大音量。
如果要使用Player接口播放,还需要引入javax.microedition.media.control包。
try{
byte tempo = 30; //设置声音播放速度
byte d = 8; //音调值
byte C4 = ToneControl.C4; //音调值,基准音调
byte D4 = (byte)(C4 + 2); //音调值
byte E4 = (byte)(C4 + 4); //音调值
byte G4 = (byte)(C4 + 7); //音调值
byte rest = ToneControl.SILENCE; //音调值,无声
byte[]mySequence = {
ToneControl.VERSION, 1, //设置版本号,当前必须设为1
ToneControl.TEMPO, tempo,//设置声音播放速度,值越大,播放越快
ToneControl.SET_VOLUME, 50,//设置音量,值越大,音量越大
ToneControl.BLOCK_START, 0,//预定义播放块, 当前块号为0
E4, d, D4, d, C4, d, E4, d,//
E4, d, E4, d, E4, d, rest, d,//块的内容
ToneControl.BLOCK_END, 0,//块定义结束符
ToneControl.PLAY_BLOCK,0,//播放当前块号为0的块,块号必须提前定义
D4, d, D4, d, D4, d, rest, d,//不使用块号方式播放的内容,必须位于块定义后面
};
Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);//创建播放器
p.realize();//准备播放信息
ToneControl c = (ToneControl)p.getControl("ToneControl");//获取音调控制
c.setSequence(mySequence);//设置音调序列
p.prefetch();//设置播放资源,获取设备
p.start();//开始播放
}catch(Exception e){
System.out.println(e);
}
上面播放了音调序列,这里有个需要注意的地方,必须使用Manager.TONE_DEVICE_LOCATOR为参数创建播放器,才能够播放声音序列。声音序列的格式,必须严格遵守定义的格式,出现任何错误都无法正确播放声音。
关于realize的调用在创建接口后发生,这样就获取了足够的播放信息,但是此时没有播放的资源。使用getControl()方法,获取音调控制接口,只有使用它才能够设置播放资源。最后获取资源,播放声音。
2.播放音乐文件
播放音乐文件有两种方法,分别对应于不同的创建播放器接口方法。首先是播放Jar中的声音文件:
try{
InputStream is = getClass().getResourceAsStream("/Testsound.mid");
Player player = Manager.createPlayer(is, "audio/midi");
player.realize();
player.prefetch();
player.start();
}catch(Exception e){
System.out.println(e);
}
这里播放声音的方式只是普通的获取资源,然后播放声音。如果使用网络方式播放声音除了播放的延时有些长外,没有什么特殊效果。但是必须注意,使用的协议必须支持播放的声音格式。
try{
Player player = Manager.createPlayer("http://www.sodino.com/sound.mid");
player.realize();
player.prefetch();
player.start();
}catch(Exception e){
System.out.println(e);
}
3.控制播放音量及播放次数
对于播放的声音,有时需要控制音量的大小,或者设置为静音,都需要音量控制接口。首先必须获得音量控制接口,如果这种声音格式支持音量控制,查询获得的音量接口将不会为null。音量设置的级别为0~100,100为最大音量,超过100,则会被设为100。
try {
InputStream is = getClass().getResourceAsStream("Testsound.mid");
Player player = Manager.createPlayer(is, "audio/midi");
player.realize();
// 获得控制接口,此接口的获得必须在获取播放信息或获取播放设备后面,如果在它们前面,将会出现无法播放的情况
VolumeControl control = (VolumeControl) player
.getControl("VolumeControl");
if (control != null) {// 必须检查是否为null,因为有些声音格式可能不支持音量控制
control.setLevel(50); // 设置音量级别为50
// control.setMuto(true);//设置静音
}
player.prefetch();// 获取设备,音量控制可以放在它后面
player.setLoopCount(2);//设置循环两次,设为-1为无穷循环
player.start();// 播放声音,音量可以在开始播放后改变
player.stop();
player.setLoopCount(-1);//必须声音停止后才能够重新设置播放次数
player.start();//再次播放
} catch (Exception e) {
System.out.println(e);
}
4.播放器监听接口
public class ExPlayer implements PlayerListener {
// 实现playerUpdate接口
public void playerUpdate(Player player, String event, Object eventData) {
if (event == PlayerListener.END_OF_MEDIA) {
try {
player.start();
} catch (Exception e) {
System.out.println(e);
}
}
}
public ExPlayer() {
}
public void allAction(){
try{
InputStream is = getClass().getResourceAsStream("/sound.mid");
Player player = Manager.createPlayer(is, "audio/midi");
//注册PlayerListener接口,可以放在创建接口后面的任何位置,包括开始播放以后,建议放在播放之前,这样出现错误的可能性小。
player.addPlayerListener(this);
player.realize();
player.prefetch();
player.start();
}catch(Exception e){
System.out.println(e);
}
}
}
5.以独占方式播放声音
package SoundTest;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.control.VolumeControl;
public class AudioPlayerSample {
private Player player;
private String filename;
private String format;
public AudioPlayerSample(String fn, String f, boolean isLoad) {
format = f;
filename = fn;
if (isLoad) {
loadResource();
}
}
public AudioPlayerSample(String fn, String f) {
format = f;
filename = fn;
}
public void loadResource() {
InputStream is = getClass().getResourceAsStream("/test.mid");
try {
player = Manager.createPlayer(is, format);
} catch (IOException e) {
e.printStackTrace();
} catch (MediaException e) {
e.printStackTrace();
}
}
public void setLoop() {
if (player != null) {
player.setLoopCount(-1);
}
}
public void setVolume(int level) {
if (player != null) {
VolumeControl control = (VolumeControl) player
.getControl("VolumeControl");
control.setLevel(level);
}
}
public void stop() {
if (player != null) {
try {
player.stop();
} catch (MediaException e) {
e.printStackTrace();
}
}
}
public void play() {
if (player != null) {
try {
player.realize();
player.prefetch();
player.start();
} catch (MediaException e) {
System.out.println(e);
}
}
}
public void replay() {
close();
System.gc();
loadResource();
play();
}
public void close() {
if (player != null) {
player.close();
player = null;
}
}
}
该类的一些用法 :
//构造对象,但是没有进行资源的载入,只是记录了文件名和格式
AudioPlayerSample apsPlayer = new AudioPlayerSample("Testsound.mid","audio/midi");
AudioPlayerSample apsPlayer02 = new AudioPlayerSample("bg.mid","audio/midi");
apsPlayer.loadResource();//装载资源
apsPlayer.play();//播放声音
//......//游戏中的其它操作
//由于声音设备独占的问题,必须关闭上一个声音,才能播放下一个声音
apsPlayer.close();
apsPlayer02.replay();
6.以线程方式播放声音
public class AudioPlayerSample implements Runnable{
public void run(){}
public void threadPlay(){ new Thread(this).start(); }}