站内搜索: 请输入搜索关键词
当前页面: 图书首页 > Programming Wireless Devices with the Java2 Platform

Programming Wireless Devices with the Java2 Platform

[ directory ] Previous Section Next Section

13.2 Player Creation and Management

In this section, the process of creating and managing sound in a MIDP 2.0 application is described. The functionality of classes Manager and Player are described, and simple application examples are provided to illustrate the details of the API.

Figure 13.2 shows the class diagram of the MIDP 2.0 Sound API. (Interfaces are shown in italic font.)

Figure 13.2. Class diagram of the MIDP Sound API

graphics/13fig02.gif

13.2.1 Managing a Media Framework

The entry point to the Sound API is the Manager class. Class Manager provides access to an implementation-specific mechanism for constructing Player objects. In addition, class Manager provides means for property queries of content and protocol support. For convenience, it also provides a simplified method to generate simple tones.

Property queries

The MIDP sound API provides a mechanism for querying the type of content and protocols that the device supports. The property queries are enabled by the methods Manager.getSupportedContentTypes and Manager.getSupportedProtocols.

For example, if the given protocol is "http:", then the supported content types that can be played back with the http protocol will be returned. If null is passed in as the protocol, all the supported content types for this device will be returned. The returned array must be non-empty; in other words, at least one content type has to be supported.

13.2.2 Creating Players for Media Data

The Player interface controls the rendering of time-based media data. It provides the methods to manage the life cycle of the Player, controls the playback progress, and obtains the presentation components.

A Player can be created using one of the two createPlayer methods of the Manager class:

// Create a Player to play back media from an InputStream
createPlayer(java.io.InputStream stream, String type)

// Create a Player from an input locator
createPlayer(String locator)

When a Player is created from an InputStream, the type argument specifies the content type of the input media. If null is given, Manager will attempt to determine the type. However, since determining the media type is non-trivial for some media types, it may not be feasible in some cases; Manager may throw a MediaException to indicate the occurrence of such a situation.

A Player can also be created using a locator. In this case, a locator string is given in URI syntax that describes the media content.

After the Player object is created, it will enter the STARTED state when the program calls the method Player.start. This method will start the playback as soon as possible and will return when the playback is started. The playback will continue in the background and will stop automatically when the end of media is reached. The MIDP Sound API Player states are described in detail in Figure 13-3 and in "Player life cycle" on page 204.

Figure 13.3. MIDP Sound API Player state diagram

graphics/13fig03.gif

Data sources for media

Content types identify the type of media data for Player objects when the Player is created using an InputStream. These content types are defined to be the registered MIME types[1] . In addition, there are some user-defined types that generally follow the MIME syntax (RFC 2045, RFC 2046).

[1] See http://www.iana.org/assignments/media-types/ for details of registered MIME types for media.

For example, here are a few common content types:

  • Tone sequences: audio/x-tone-seq

  • Wave audio files: audio/x-wav

  • AU audio files: audio/basic

  • MP3 audio files: audio/mpeg

  • MIDI files: audio/midi

When a Player is created using a media locator, the locator is specified in URI syntax defined in the following form:

<scheme>:<scheme-specific-part>

The "scheme" part of the locator string identifies the name of the protocol being used to deliver the data. For instance, "http://webserver/music.mid" is an example of a valid locator string.

Player life cycle

A typical media player features the basic commands (or state transition methods) for starting and stopping media playback. In resource-constrained devices, however, special care must be taken to optimize the media playback process for applications. Therefore, the MIDP 2.0 media player architecture features additional states, which are described in more detail below.

Figure 13.3 shows a state diagram that illustrates the MIDP 2.0 Player life cycle. The Player object has five states: UNREALIZED, REALIZED, PREFETCHED, STARTED, and CLOSED. The purpose of these life-cycle states is to provide programmatic control over the use of media resources and potentially time-consuming operations. For example, when a Player is first constructed, it's in the UNREALIZED state. When the state changes from UNREALIZED to REALIZED, the Player performs the communication necessary to locate all of the resources it needs to function (such as communicating with a server or a file system). The realize method allows an application to initiate this potentially time-consuming process at an appropriate time.

Typically, a Player moves from the UNREALIZED state to the REALIZED state, then to the PREFETCHED state, and finally on to the STARTED state. A Player stops when it reaches the end of media or when the stop method is invoked. When that happens, the Player moves from the STARTED state back to the PREFETCHED state. Upon calling the Player.stop method, the playback position in the file does not change, so calling Player.start again will continue the playback from the same location. In Figure 13.3, the gray-shaded boxes represent the reservation of audio resource in hardware.

The basic use of a Player only requires the Player.start and Player.stop methods. However, in order to fully utilize all the functionality of the Player, parameters must be set up appropriately to manage the life-cycle states, and the state transition methods should be used correctly to advance between the various Player states.

Additional Player functionalities include looping of audio using the setLoopCount method, and obtaining or setting the current position of media playback using the getMediaTime and setMediaTime methods. Furthermore, the getDuration method can be used to query the length of the media file.

PlayerListener

Class PlayerListener defines an interface that can be used for receiving asynchronous events generated by Player objects. Applications can implement this interface and register their implementations with the addPlayerListener method of class Player.

A number of standard Player events are defined in the PlayerListener interface. Event types are defined as Strings in order to support extensibility because different implementations may introduce proprietary events by adding new event types. The predefined, standard event types are as follows:

  • CLOSED. Posted when a Player is closed. The Player may be closed either by the user, or it may be closed by the system after an irrecoverable error has occurred.

  • DEVICE_AVAILABLE. Posted when the system or another higher priority application has released an exclusive device that is now available to the Player.

  • DEVICE_UNAVAILABLE. Posted when the system or another higher priority application has temporarily taken control of an exclusive device that was previously available to the Player.

  • DURATION_UPDATED. Posted when the duration of a Player is updated.

  • END_OF_MEDIA. Posted when a Player has reached the end of the media.

  • ERROR. Posted when an error had occurred.

  • STARTED. Posted when a Player is started.

  • STOPPED. Posted when a Player stops in response to the stop method call.

  • VOLUME_CHANGED. Posted when the volume of an audio device is changed.

The playerUpdate method is called to deliver an event to a registered listener when a Player event is observed.

13.2.3 Tone Generation

The minimal requirement for all MIDP 2.0 devices is to support the playback of monophonic single tones. Tone generation is important for games and other audio applications. On resource-constrained devices, this is particularly important since tone generation is likely to be the only form of audio capabilities supported.

In its simplest form, tone generation is implemented as a single buzzer or simple monophonic tone generation. This feature is enabled by two different methods in the MIDP 2.0 API.

The first possibility is to use the Manager class, which provides a method for playing back simple tones (see Section 13.2.4, "Sample Code," for an example), specified by a note and its duration. A note is given in the range of 0 to 127 inclusive. The frequency of the note can be calculated using the following formula:

SEMITONE_CONST = 17.31234049066755 = 1/(ln(2^(1/12)))
note = ln(freq/8.176)*SEMITONE_CONST
// The musical note A = MIDI note 69 (0x45) = 440 Hz.

This call is a non-blocking call. Notice that this method may utilize CPU resources significantly on devices that do not have hardware support for tone generation.

The second possibility to create sequences of single tones is to use the ToneControl API. The use of this API is discussed in more detail in Section 11.3.1.

13.2.4 Sample Code

In this section, a few simple examples are provided to illustrate tone generation and the creation of new Players using the methods of class Manager.

Example: Single tone generation
try {
    Manager.playTone(ToneControl.C4 /* note */,
                     5000           /* duration in ms */,
                     100            /* max vol */);
} catch (MediaException e) {
}
Example: Creating a player from media stored in JAR

Notice that in MIDP 2.0 the wav format is mandatory only in case the device supports sampled audio.

try {
    InputStream is = getClass().getResourceAsStream("music.wav");
    Player p = Manager.createPlayer(is, "audio/X-wav");
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}
Example: Creating a player from media in HTTP locator
try {
    Player p = Manager.createPlayer("http://webserver/music.mid");
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}

Notice that in MIDP 2.0, the MIDI format (SP-MIDI) is mandatory only when the device supports sampled audio.

    [ directory ] Previous Section Next Section