Navigace

Hlavnφ menu

 

J2ME v kostce - jak na zvuk I

Ve standardnφm MIDP 1.0 byste podporu zvuku hledali marn∞. Co s tφm, pokud p°esto chcete u₧ivatele sv²ch her obÜ¥astnit ·chvatn²mi a nezapomenuteln²mi zvuky, bez nich₧ by to prost∞ nebylo ono? Cht∞ necht∞ budete muset nejspφÜ pou₧φt proprietßrnφ API v²robc∙ telefon∙. V tomto Φlßnku vßs seznßmφm s Φßstφ Mobile Multimedia API, t²kajφcφ se zvuku.

Mobile Media API

Knihovna Mobile Media API (MMAPI - JSR-135) rozÜi°uje J2ME o prßci s multimΘdii, nap°φklad audiem a videem. Podmno₧ina MMAPI, zab²vajφcφ se zvukem, je souΦßstφ MIDP 2.0, ale vyskytuje se i na nezanedbatelnΘm mno₧stvφ telefon∙, kterΘ implementujφ pouze MIDP 1.0. Jak tvrdφ p°ehled telefon∙ s J2ME p°φmo u Sunu, jde o nov∞jÜφ telefony od firem Nokia a Sony Ericsson. MMAPI se vyskytuje i na n∞kter²ch telefonech znaΦky Siemens (nejspφÜ na vÜech krom∞ starÜφch model∙ jako SL45i, M50, MT50), jenom s tou fintou, ₧e se odpovφdajφcφ t°φdy nenachßzejφ v balφcφch javax.microedition.media a javax.microedition.media.control, ale v balφcφch com.siemens.mp.media a com.siemens.mp.media.control.

Zßkladnφ t°φdou MMAPI je t°φda javax.microedition.media.Manager. Tato t°φda dle zadan²ch parametr∙ vytvo°φ instanci rozhranφ javax.microedition.media.Player, kterß slou₧φ k p°ehrßvßnφ zvukov²ch soubor∙ nebo jednohlas²ch sekvencφ t≤n∙. Nastavenφ t°φdy typu javax.microedition.media.Player se dßle m∙₧e ovliv≥ovat t°φdami typu javax.microedition.media.Control.

Architektura MMAPI
Architektura MMAPI

Manager

T°φda Manager umφ vytvo°it instanci t°φdy Player ze vstupnφho proudu nebo na zßklad∞ zadanΘho URI. Prvnφ metoda je urΦena k p°ehrßvßnφ zvukov²ch soubor∙ ulo₧en²ch v JARu a jejφ pou₧itφ je nßsledujφcφ:

try {
    // otev°enφ zvukovΘho souboru v JARu
    InputStream is = getClass()
        .getResourceAsStream("music.wav");
    // vytvo°enφ instance t°φdy Player,
    // kterß umφ p°ehrßt onen zvukov² soubor
    Player p = Manager.createPlayer(is, "audio/x-wav");
    // nastavenφ poΦtu opakovßnφ zßznamu
    p.setLoopCount(13);
    // spuÜt∞nφ p°ehrßvßnφ
    p.start();
} catch (IOException ioe) {
    // nastal problΘm se Φtenφm proudu
} catch (MediaException me) {
    // Player po₧adovanΘho typu nelze vytvo°it
}

Pokud se v JARu zvukov² soubor nenachßzφ, zkonΦφ b∞h p°edchozφho k≤du v²jimkou NullPointerException, proto₧e v tom p°φpad∞ vrßtφ metoda getResourceAsStream("music.wav") hodnotu null.

Nachßzφ-li se zvukov² soubor mimo JAR soubor aplikace, je pot°eba k jeho p°ehrßnφ pou₧φt metodu Manager.createPlayer(String URI). URI je definovßno schΘmatem:

<protokol>:<podrobnosti zßvislΘ na protokolu>

P°φklady URI:

http://www.mujserver.cz/moje.mp3
ftp://nejaky.ftp.server.com/cizi.wav

Povinn∞ podporovanΘ typy zvukov²ch soubor∙ jsou v MIDP 2.0 "WAV (audio/x-wav)" a "MIDI (audio/midi)", nejlepÜφ je zjistit si na ka₧dΘm telefonu seznam vÜech podporovan²ch typ∙ metodou getSupportedContentTypes(String protokol). Zavolß-li se s parametrem null, vrßtφ podporovanΘ typy bez ohledu na protokol. Nap°φklad telefony Sony Ericsson um∞jφ p°ehrßvat "MIDI (audio/midi)", "AMR (audio/amr)" a "iMelody (audio/imelody)".

Na p°ehrßnφ jednoho t≤nu mß t°φda Manager metodu playTone(int vyska, int delka, int hlasitost). V²Üka t≤nu je Φφslo od 0 do 127, p°iΦem₧ t≤nu c1 odpovφdß hodnota 60 a dßle v₧dy hodnoty liÜφcφ se o 1 odpovφdajφ notßm liÜφcφm se o p∙lt≤n.

Player

Rozhranφ Player slou₧φ k p°ehrßvßnφ zvukov²ch dat. B∞hem svΘho ₧ivotnφho cyklu se m∙₧e ocitnout v n∞kolika stavech:

Nerealizovan² stav

V tomto stavu se Player nachßzφ po svΘm vytvo°enφ. Proto₧e nemß jeÜt∞ dostatek informacφ o zvukov²ch datech, nelze v tomto stavu volat metody:

  • getContentType()
  • setMediaTime()
  • getControls()
  • getControl()

Do nßsledujφcφho stavu p°ejde Player zavolßnφm metody realize(). Jsou-li nap°φklad zvukovß data umφst∞na na serveru, jsou v pr∙b∞hu realizace sta₧ena na mobilnφ telefon.

Realizovan² stav

Zvukovß za°φzenφ se jeÜt∞ nealokujφ, aby zbyteΦn∞ nebyla blokovßna. Do nßsledujφcφho stavu se p°ejde metodou prefetch().

P°ipraven² stav

P°echod z p°ipravenΘho do b∞₧φcφho stavu by m∞l trvat minimum Φasu, proto v p°ipravenΘm stavu u₧ jsou alokovßna zvukovß za°φzenφ a zßsobnφky napln∞ny zvukov²mi daty, je-li to pot°eba. Do nßsledujφcφho stavu se p°ejde metodou start(). Po ukonΦenφ svΘho b∞hu se Player op∞t vrßtφ do p°ipravenΘho stavu.

B∞₧φcφ stav

V b∞₧φcφm stavu Player p°ehrßvß zvukovß data. V tomto stavu nenφ u₧ mo₧nΘ nastavovat poΦet opakovßnφ zvuku metodou setLoopCount().

UkonΦen² stav

Do ukonΦenΘho stavu p°ejde Player z jakΘhokoli stavu volßnφm metody close(). V tomto stavu uvolnφ vÜechny zdroje a nedß se u₧ dßle pou₧φt.

Player - stavy
Player - ₧ivotnφ cyklus

Obrßzek ukazuje cel² ₧ivotnφ cyklus objektu typu Player. Pro lepÜφ p°ehlednost z n∞j byly vypuÜt∞ny n∞kterΘ Üipky. Je-li Player v nerealizovanΘm stavu a zavolß se metoda prefetch() nebo start(), automaticky je zavolßna jako jejich souΦßst metoda realize(). Je-li Player v realizovanΘm stavu a zavolß se na n∞m metoda start(), automaticky je zavolßna jako jejφ souΦßst metoda prefetch().

Udßlosti

Pot°ebujeme-li dostßvat informace o zm∞nßch stavu t°φdy typu Player, je pot°eba implementovat rozhranφ PlayerListener, kterΘ obsahuje pouze jednu metodu playerUpdate(Player player, String typUdalosti, Object data), a dßle si posluchaΦe zaregistrovat metodou addPlayerListener(PlayerListener posluchac). VÜechny typy udßlostφ, kterΘ posluchaΦ m∙₧e dostßvat, obsahuje rozhranφ PlayerListener jako statickΘ prom∞nnΘ. Chceme-li, aby po celou dobu spuÜt∞nφ aplikace hrßla na pozadφ dokola jedna skladba a nastavenφ vysokΘho poΦtu opakovßnφ skladby se nßm nezdß jako dostateΦn∞ vhodnß metoda, m∙₧eme si zaregistrovat posluchaΦe a p°i odchycenφ udßlosti END_OF_MEDIA volat na t°φdu typu Player metodu start().

Control

Rozhranφ Control neobsahuje ₧ßdnΘ metody spoleΦnΘ pro ovladaΦe zvuku, slou₧φ pouze jako p°edek, ze kterΘho musφ b²t vÜechny odvozeny. V MIDP 2.0 jsou definovßna v balφku javax.microedition.media.control dv∞ rozhranφ, rozÜi°ujφcφ Control, a to VolumeControl a ToneControl.

VolumeControl

Rozhranφ VolumeControl slou₧φ poze k nastavenφ hlasitosti zvuku. Hlasitost m∙₧e nab²vat hodnotu od 0 do 100. Hodnota 0 odpovφdß vypnutΘmu zvuku a 100 nejvyÜÜφ mo₧nΘ hlasitosti.

// zφskßnφ ovladaΦe hlasitosti, podle dokumentace nenφ-li
// pou₧it² nßzev t°φdy absolutnφ, p°edpoklßdß se,
// ₧e je z balφku javax.microedition.media.control
VolumeControl volume = (VolumeControl)
          player.getControl("VolumeControl");
// nastavenφ hlasitosti na nejvyÜÜφ mo₧nou hodnotu
volume.setLevel(100);

ToneControl

Rozhranφ ToneControl slou₧φ k p°ehrßvßnφ jednohlas²ch sekvencφ t≤n∙. Toto rozhranφ nenφ obsa₧eno v telefonech znaΦky Siemens. Pokud u₧ mßme sekvenci t≤n∙ vytvo°enou, p°ehraje se takto:

    // sekvence t≤n∙ jako pole byt∙
byte[] mySequence = ...
try {
    // vytvo°enφ t°φdy typu Player na p°ehrßvßnφ sekvencφ t≤n∙
    Player mp = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
    // p°echod do realizovanΘho stavu
    mp.realize();
    // zφskßnφ ovladaΦe typu ToneControl
    ToneControl c = (ToneControl)
        mp.getControl("ToneControl");
    // nastavenφ skevence t≤n∙
    c.setSequence(mySequence);
    // spuÜt∞nφ p°ehrßvßnφ
    mp.start();
} catch (Exception ex) {
    // zpracovßnφ v²jimky
}

┌plnß definice formßtu sekvence t≤n∙ je pon∞kud delÜφ, proto ji uvßdφm v externφm souboru.

Poznßmka k MIDP 2.0

Pokud vßs blφ₧e zajφmß MIDP 2.0, je prßv∞ v tisku Φesk² p°eklad knihy J2ME v kostce, kterou vydßvß Grada. Tato kniha bude obsahovat takΘ mou p°φlohu, zab²vajφcφ se prßv∞ MIDP 2.0.

Odkazy, zdroje

Bittnerovß, Lucie Rut (6. 4. 2004)
programßtor û analytik Amaio Technologies