站内搜索: 请输入搜索关键词
当前页面: 图书首页 > Wireless Java Developing with J2ME, Second Edition

Quick Start - Wireless Java Developing with J2ME, Second Edition

Previous Section Next Section

Quick Start

You can play tones by calling this method in javax.microedition.media.Manager:

public static void playTone(int note, int duration, int volume)

In this method, note is specified just like a MIDI note, where each integer corresponds to a single key on a piano keyboard. Middle C is 60, and the A above middle C (a 440 Hz tone) is 69. The duration is in milliseconds, and volume can range from 0, silent, to 100, loudest.

Like most other methods in the ABB, playTone() may throw a MediaException. Although support for simple tones is required by the specification, the device may be temporarily unable to play tones. (For example, a mobile phone might be using the tone generation hardware to ring the phone.)

Figure 12-1 shows PianoCanvas, an example that displays a simple piano keyboard and allows the user to navigate through the keys to play different tones. PianoCanvas is presented in Listing 12-1. The code for playing the tones is very compact, consisting solely of a call to playTone() in the keyPressed() method. The rest of the code is devoted to the user interface.

Listing 12-1: PianoCanvas Source Code
Start example
import javax.microedition.lcdui.*;
import javax.microedition.media.*;

public class PianoCanvas
    extends Canvas {
  private static final int[] kNoteX = {
     0, 11, 16, 29, 32, 48, 59, 64, 76, 80, 93, 96
  };

  private static final int[] kNoteWidth = {
    16, 8, 16, 8, 16, 16, 8, 16, 8, 16, 8, 16
  };

  private static final int[] kNoteHeight = {
    96, 64, 96, 64, 96, 96, 64, 96, 64, 96, 64, 96
  };

  private static final boolean[] kBlack = {
    false, true, false, true, false,
        false, true, false, true, false, true, false
  };

  private int mMiddleCX, mMiddleCY;
  private int mCurrentNote;

  public PianoCanvas() {
    int w = getWidth();
    int h = getHeight();

    int fullWidth = kNoteWidth[0] * 8;
    mMiddleCX = (w - fullWidth) / 2;
    mMiddleCY = (h - kNoteHeight[0]) / 2;

    mCurrentNote = 60;
  }

  public void paint(Graphics g) {
    int w = getWidth();
    int h = getHeight();

    g.setColor(0xffffff);
    g.fillRect(0, 0, w, h);
    g.setColor(0x000000);

    for (int i = 60; i <= 72; i++)
      drawNote(g, i);

    drawSelection(g, mCurrentNote);
  }

  private void drawNote(Graphics g, int note) {
    int n = note % 12;
    int octaveOffset = ((note - n) / 12 - 5) * 7 * kNoteWidth[0];
    int x = mMiddleCX + octaveOffset + kNoteX[n];
    int y = mMiddleCY;
    int w = kNoteWidth[n];
    int h = kNoteHeight[n];

    if (isBlack(n))
      g.fillRect(x, y, w, h);
    else
      g.drawRect(x, y, w, h);
  }

  private void drawSelection(Graphics g, int note) {
    int n = note % 12;
    int octaveOffset = ((note - n) / 12 - 5) * 7 * kNoteWidth[0];
    int x = mMiddleCX + octaveOffset + kNoteX[n];
    int y = mMiddleCY;
    int w = kNoteWidth[n];
    int h = kNoteHeight[n];

    int sw = 6;
    int sx = x + (w - sw) / 2;
    int sy = y + h - 8;
    g.setColor(0xffffff);
    g.fillRect(sx, sy, sw, sw);
    g.setColor(0x000000);
    g.drawRect(sx, sy, sw, sw);
    g.drawLine(sx, sy, sx + sw, sy + sw);
    g.drawLine(sx, sy + sw, sx + sw, sy);
  }

  private boolean isBlack(int note) {
    return kBlack[note];
  }

  public void keyPressed(int keyCode) {
    int action = getGameAction(keyCode);
    switch (action) {
      case LEFT:
        mCurrentNote--;
        if (mCurrentNote < 60)
          mCurrentNote = 60;
        repaint();
        break;
      case RIGHT:
        mCurrentNote++;
        if (mCurrentNote > 72)
          mCurrentNote = 72;
        repaint();
        break;
      case FIRE:
        try { Manager.playTone(mCurrentNote, 1000, 100); }
        catch (MediaException me) {}
        break;
      default:
        break;
    }
  }
}

End example

Figure 12-1: An itty bitty piano

The ABB also offers support for playing sampled audio files, although the specification does not require support for this feature. To play sampled audio, you just need to get a Player for the data you wish to hear, then start the Player running. You can get a Player by asking Manager for one. In its simplest form, playing sampled audio data looks like this:

URL url = "http://65.215.221.148:8080/wj2/res/relax.wav";
Player p = Manager.createPlayer(url);
p.start();

In this approach, the web server provides the content type of the data. Another approach is to obtain an InputStream to the audio data, then create a Player by telling Manager the content type of the data. This is handy for reading audio files that are stored as resources in the MIDlet suite JAR. For example:

InputStream in = getClass().getResourceAsStream("/relax.wav");
Player player = Manager.createPlayer(in, "audio/x-wav");
player.start();

Listing 12-2 is a simple MIDlet that demonstrates both techniques.

Listing 12-2: Playing Audio Files
Start example
import java.io.*;

import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.media.*;

public class AudioMIDlet
    extends MIDlet
    implements CommandListener, Runnable {
  private Display mDisplay;
  private List mMainScreen;

  public void startApp() {
    mDisplay = Display.getDisplay(this);

    if (mMainScreen == null) {
      mMainScreen = new List("AudioMIDlet", List.IMPLICIT);
      mMainScreen.append("Via HTTP", null);
      mMainScreen.append("From resource", null);
      mMainScreen.addCommand(new Command("Exit", Command.EXIT, 0));
      mMainScreen.addCommand(new Command("Play", Command.SCREEN, 0));
      mMainScreen.setCommandListener(this);
    }

    mDisplay.setCurrent(mMainScreen);
  }

  public void pauseApp() {}

  public void destroyApp(boolean unconditional) {}

  public void commandAction(Command c, Displayable s) {
    if (c.getCommandType() == Command.EXIT) notifyDestroyed();
    else {
      Form waitForm = new Form("Loading...");
      mDisplay.setCurrent(waitForm);
      Thread t = new Thread(this);
      t.start();
    }
  }

  public void run() {
    String selection = mMainScreen.getString(
        mMainScreen.getSelectedIndex());
    boolean viaHttp = selection.equals("Via HTTP");

    if (viaHttp)
      playViaHttp();
    else
      playFromResource();
  }

  private void playViaHttp() {
    try {
      String url = getAppProperty("AudioMIDlet-URL");
      Player player = Manager.createPlayer(url);
      player.start();
    }
    catch (Exception e) {
      showException(e);
      return;
    }
    mDisplay.setCurrent(mMainScreen);
  }

  private void playFromResource() {
    try {
      InputStream in = getClass().getResourceAsStream("/relax.wav");
      Player player = Manager.createPlayer(in, "audio/x-wav");
      player.start();
    }
    catch (Exception e) {
      showException(e);
      return;
    }
    mDisplay.setCurrent(mMainScreen);
  }

  private void showException(Exception e) {
    Alert a = new Alert("Exception", e.toString(), null, null);
    a.setTimeout(Alert.FOREVER);
    mDisplay.setCurrent(a, mMainScreen);
  }
}
End example

Previous Section Next Section