作者:mingjava 文章来源:http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=147
Nokia UI API的目的在于提供一些MIDP1.0中没有提供的功能,本文讲述如何使用Nokia UI中提供的声音处理的API。在com.nokia.mid.sound包中有一个Sound类和SoundListener接口,SoundListener接口的作用就是当播放的状态转换的时候,监听器中的方法被调用,也就是我们常说的回调。这里不做介绍了。
Sound类封装了用于播放声音的方法,手机所能支持的声音格式和并行播放的数量是和设备相关的,我们可以通过方法supportedFormat = Sound.getSupportedFormats();
Sound.getConcurrentSoundCount()方法得到这些数据。下面提供一个小程序用户判断我的手机nokia 6108所能支持的声音类型和并行播放的数量。
package com.j2medev.test;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import com.nokia.mid.sound.*;
public class NokiaSound extends MIDlet
{
private Display display;
private Form mainForm;
private int[] supportedFormat;
protected void startApp() throws MIDletStateChangeException
{
initMIDlet();
}
public void initMIDlet()
{
display = Display.getDisplay(this);
mainForm = new Form("Nokia Sound");
supportedFormat = Sound.getSupportedFormats();
if (supportedFormat.length == 0)
{
mainForm.append("No audio format supported!");
} else
{
for (int i = 0; i < supportedFormat.length; i++)
{
mainForm.append("" + supportedFormat[i] + " : "
+ Sound.getConcurrentSoundCount(supportedFormat[i]));
}
}
display.setCurrent(mainForm);
}
protected void pauseApp()
{
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException
{
}
}
程序运行在nokia 6108上显示1:1表示本机支持单音,并行播放数量也是1。
Sound类有两个构造器
Sound(byte[] data, int type)
Sound(int freq, long duration)
我们主要讲述后者,通过提供给构造器或者init(int freq,long duration)方法适当的频率和持续时间来初始化声音对象,通过调用play()方法可以播放声音,调用stop方法可以停止声音的播放。关于Sound类提供的其他API请参考Nokia Ui java doc。这里给出频率参数
Freq off 0
Ring freq A0 220
Ring freq B0b 233
Ring freq B0 247
Ring freq C0 262
Ring freq D0b 277
Ring freq D0 294
Ring freq E0b 311
Ring freq E0 330
Ring freq F0 349
Ring freq G0b 370
Ring freq G0 392
Ring freq A1b 416
Ring freq A1 440
Ring freq B1b 466
Ring freq B1 494
Ring freq C1 523
Ring freq D1b 554
Ring freq D1 587
Ring freq E1b 622
Ring freq E1 659
Ring freq F1 698
Ring freq G1b 740
Ring freq G1 784
Ring freq A2b 831
Ring freq A2 880
Ring freq B2b 932
Ring freq B2 988
Ring freq C2 1047
Ring freq D2b 1109
Ring freq D2 1175
Ring freq E2b 1245
Ring freq E2 1319
Ring freq F2 1397
Ring freq G2b 1480
Ring freq G2 1568
Ring freq A3b 1661
Ring freq A3 1760
Ring freq B3b 1865
Ring freq B3 1976
Ring freq C3 2093
Ring freq D3b 2217
Ring freq D3 2349
Ring freq E3b 2489
Ring freq E3 2637
Ring freq F3 2794
Ring freq G3b 2960
Ring freq G3 3136
Ring freq A4b 3322
Ring freq A4 3520
Ring freq B4b 3729
Ring freq B4 3951
Ring freq C4 4186
Ring freq D4b 4434
Ring freq D4 4698
Ring freq E4b 4978
Ring freq E4 5274
Ring freq F4 5588
Ring freq G4b 5920
Ring freq G4 6272
Ring freq A5b 6644
Ring freq A5 7040
Ring freq B5b 7458
Ring freq B5 7902
Ring freq C5 8372
Ring freq D5b 8870
Ring freq D5 9396
Ring freq E5b 9956
Ring freq E5 10548
Ring freq F5 11176
Ring freq G5b 11840
Ring freq G5 12544
Ring freq A6b 13288
下面我们编写一个小程序来讲述如何使用Nokia UI来处理声音问题,我们的目的是当用户按下按键的时候开始播放声音,当用户释放按键的时候停止播放,我们提供一个ToneCanvas类来显示用户按下的键,并通过TonePlayer类来播放适当频率的声音。
package com.j2medev.tone;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import com.nokia.mid.ui.FullCanvas;
public class TonesCanvas extends FullCanvas
{
private TonesMIDlet midlet;
private int pressNum;
private int currentKey;
private TonePlayer player = new TonePlayer();
private static int freq[][] = { { 523, 554 }, { 587, 622 }, { 659, 659 },
{ 698, 740 }, { 784, 831 }, { 880, 932 }, { 988, 988 },
{ 1047, 1109 }, { 1175, 1245 }, { 1319, 1319 }, { 1397, 1480 } };
public static final int NAT = 0;
public static final int SHARP = 1;
private int x = this.getWidth() / 2;
private int y = this.getHeight() / 2;
private boolean sharp = false;
public TonesCanvas(TonesMIDlet midlet)
{
super();
this.midlet = midlet;
// TODO Auto-generated constructor stub
}
public void paint(Graphics g)
{
if (pressNum == -1)
{
return;
}
String note = (sharp == true) ? "#" : "";
g.setColor(128, 255, 18);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(124, 124, 0);
g.drawString(pressNum + note, x, y, Graphics.LEFT | Graphics.TOP);
}
public void keyPressed(int keyCode)
{
if (keyCode == Canvas.KEY_POUND)
{
sharp = !sharp;
} else
{
switch (keyCode)
{
case Canvas.KEY_NUM0:
pressNum = 0;
break;
case Canvas.KEY_NUM1:
pressNum = 1;
break;
case Canvas.KEY_NUM2:
pressNum = 2;
break;
case Canvas.KEY_NUM3:
pressNum = 3;
break;
case Canvas.KEY_NUM4:
pressNum = 4;
break;
case Canvas.KEY_NUM5:
pressNum = 5;
break;
case Canvas.KEY_NUM6:
pressNum = 6;
break;
case Canvas.KEY_NUM7:
pressNum = 7;
break;
case Canvas.KEY_NUM8:
pressNum = 8;
break;
case Canvas.KEY_NUM9:
pressNum = 9;
break;
case Canvas.KEY_STAR:
pressNum = 10;
break;
default:
pressNum = -1;
break;
}
if (pressNum != -1)
{
player.play(freq[pressNum][sharp == false ? NAT : SHARP]);
}
}
currentKey = keyCode;
repaint();
}
public void keyReleased(int keyCode)
{
if (keyCode == currentKey)
{
pressNum = -1;
player.stop();
}
repaint();
}
}
package com.j2medev.tone;
import com.nokia.mid.sound.Sound;
public class TonePlayer
{
private Sound sound;
public TonePlayer()
{
super();
sound = new Sound(0, 2000);
}
public void play(int freq)
{
sound.init(freq, 2000);
sound.play(1);
}
public void stop()
{
sound.stop();
}
}
package com.j2medev.tone;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class TonesMIDlet extends MIDlet
{
private final TonesCanvas canvas;
public TonesMIDlet()
{
canvas = new TonesCanvas(this);
}
public void startApp()
{
Display.getDisplay(this).setCurrent(canvas);
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
void exitRequested()
{
destroyApp(false);
notifyDestroyed();
}
}