J2ME v kostce – jak na zvuk 1.
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
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 – ž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
- J2ME Wireless Toolkit 2.1 – MIDP 2.0 emulátor od firmy Sun
- Sony Ericsson – informace a emulátory
- Siemens – informace a emulátory
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Gaming na HDR monitoru: Stojí to za to?
12. srpna 2024 -
Jak lze snadno upravovat soubory v PDF?
14. září 2023 -
Netcat a Ncat
8. prosince 2022
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024