<p id='prepend'>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.</p>
<h3>Mobile Media API</h3>
<p>Knihovna <a href='http://java.sun.com/products/mmapi/overview.html'>Mobile Media API</a> (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φ <a href='http://jal.sun.com/webapps/device/device?api=41'>p°ehled telefon∙ s J2ME</a> 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 <code>javax.microedition.media</code> a <code>javax.microedition.media.control</code>, ale v balφcφch <code>com.siemens.mp.media</code> a <code>com.siemens.mp.media.control</code>.</p>
<p>Zßkladnφ t°φdou MMAPI je t°φda <code>javax.microedition.media.Manager</code>. Tato t°φda dle zadan²ch parametr∙ vytvo°φ instanci rozhranφ <code>javax.microedition.media.Player</code>, kterß slou₧φ k p°ehrßvßnφ zvukov²ch soubor∙ nebo jednohlas²ch sekvencφ t≤n∙. Nastavenφ t°φdy typu <code>javax.microedition.media.Player</code> se dßle m∙₧e ovliv≥ovat t°φdami typu <code>javax.microedition.media.Control</code>.</p>
<p>T°φda <strong>Manager</strong> umφ vytvo°it instanci t°φdy <code>Player</code> 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φ:</p>
<div class='sample'>
try {
<br /> <span class='comment'>// otev°enφ zvukovΘho souboru v JARu</span>
<br /> <span class='comment'>// nastal problΘm se Φtenφm proudu</span>
<br />} catch (MediaException me) {
<br /> <span class='comment'>// Player po₧adovanΘho typu nelze vytvo°it</span>
<br />}
</div>
<p>Pokud se v JARu zvukov² soubor nenachßzφ, zkonΦφ b∞h p°edchozφho k≤du v²jimkou <code>NullPointerException</code>, proto₧e v tom p°φpad∞ vrßtφ metoda <samp>getResourceAsStream("music.wav")</samp> hodnotu <samp>null</samp>.</p>
<p>Nachßzφ-li se zvukov² soubor mimo JAR soubor aplikace, je pot°eba k jeho p°ehrßnφ pou₧φt metodu <code>Manager.createPlayer(String URI)</code>. URI je definovßno schΘmatem:</p>
<div class='sample'><protokol>:<podrobnosti zßvislΘ na protokolu></div>
<p>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 <code>getSupportedContentTypes(String protokol)</code>. Zavolß-li se s parametrem <samp>null</samp>, 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)".</p>
<p>Na p°ehrßnφ jednoho t≤nu mß t°φda <code>Manager</code> metodu <code>playTone(int vyska, int delka, int hlasitost)</code>. 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.</p>
<h3>Player</h3>
<p>Rozhranφ <strong>Player</strong> slou₧φ k p°ehrßvßnφ zvukov²ch dat. B∞hem svΘho ₧ivotnφho cyklu se m∙₧e ocitnout v n∞kolika stavech:</p>
<h4>Nerealizovan² stav</h4>
<p>V tomto stavu se <code>Player</code> nachßzφ po svΘm vytvo°enφ. Proto₧e nemß jeÜt∞ dostatek informacφ o zvukov²ch datech, nelze v tomto stavu volat metody:</p>
<div class='list'>
<ul>
<li>getContentType()</li>
<li>setMediaTime()</li>
<li>getControls()</li>
<li>getControl()</li>
</ul>
</div>
<p>Do nßsledujφcφho stavu p°ejde <code>Player</code> zavolßnφm metody <code>realize()</code>. Jsou-li nap°φklad zvukovß data umφst∞na na serveru, jsou v pr∙b∞hu realizace sta₧ena na mobilnφ telefon.</p>
<h4>Realizovan² stav</h4>
<p>Zvukovß za°φzenφ se jeÜt∞ nealokujφ, aby zbyteΦn∞ nebyla blokovßna. Do nßsledujφcφho stavu se p°ejde metodou <code>prefetch()</code>.</p>
<h4>P°ipraven² stav</h4>
<p>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 <code>start()</code>. Po ukonΦenφ svΘho b∞hu se <code>Player</code> op∞t vrßtφ do p°ipravenΘho stavu.</p>
<h4>B∞₧φcφ stav</h4>
<p>V b∞₧φcφm stavu <code>Player</code> p°ehrßvß zvukovß data. V tomto stavu nenφ u₧ mo₧nΘ nastavovat poΦet opakovßnφ zvuku metodou <code>setLoopCount()</code>.</p>
<h4>UkonΦen² stav</h4>
<p>Do ukonΦenΘho stavu p°ejde <code>Player</code> z jakΘhokoli stavu volßnφm metody <code>close()</code>. V tomto stavu uvolnφ vÜechny zdroje a nedß se u₧ dßle pou₧φt.</p>
<p>Obrßzek ukazuje cel² ₧ivotnφ cyklus objektu typu <code>Player</code>. Pro lepÜφ p°ehlednost z n∞j byly vypuÜt∞ny n∞kterΘ Üipky. Je-li <code>Player</code> v nerealizovanΘm stavu a zavolß se metoda <code>prefetch()</code> nebo <code>start()</code>, automaticky je zavolßna jako jejich souΦßst metoda <code>realize()</code>. Je-li <code>Player</code> v realizovanΘm stavu a zavolß se na n∞m metoda <code>start()</code>, automaticky je zavolßna jako jejφ souΦßst metoda <code>prefetch()</code>.</p>
<h4>Udßlosti</h4>
<p>Pot°ebujeme-li dostßvat informace o zm∞nßch stavu t°φdy typu <code>Player</code>, je pot°eba implementovat rozhranφ <code>PlayerListener</code>, kterΘ obsahuje pouze jednu metodu <samp>playerUpdate(Player player, String typUdalosti, Object data)</samp>, a dßle si posluchaΦe zaregistrovat metodou <samp>addPlayerListener(PlayerListener posluchac)</samp>. VÜechny typy udßlostφ, kterΘ posluchaΦ m∙₧e dostßvat, obsahuje rozhranφ <code>PlayerListener</code> 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 <samp>END_OF_MEDIA</samp> volat na t°φdu typu <code>Player</code> metodu <code>start()</code>.</p>
<h3>Control</h3>
<p>Rozhranφ <strong>Control</strong> 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 <code>javax.microedition.media.control</code> dv∞ rozhranφ, rozÜi°ujφcφ <code>Control</code>, a to <code>VolumeControl</code> a <code>ToneControl</code>.</p>
<h4>VolumeControl</h4>
<p>Rozhranφ <code>VolumeControl</code> 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.</p>
<div class='sample'>
<span class='comment'>// zφskßnφ ovladaΦe hlasitosti, podle dokumentace nenφ-li</span>
<br /><span class='comment'>// ₧e je z balφku javax.microedition.media.control</span>
<br />VolumeControl volume = (VolumeControl)
<br /> player.getControl("VolumeControl");
<br /><span class='comment'>// nastavenφ hlasitosti na nejvyÜÜφ mo₧nou hodnotu</span>
<br />volume.setLevel(100);
</div>
<h4>ToneControl</h4>
<p>Rozhranφ <code>ToneControl</code> 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:</p>
<div class='sample'>
<span class='comment'>// sekvence t≤n∙ jako pole byt∙</span>
<br />byte[] mySequence = ...
<br />try {
<br /> <span class='comment'>// vytvo°enφ t°φdy typu Player na p°ehrßvßnφ sekvencφ t≤n∙</span>
<br /> Player mp = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
<br /> <span class='comment'>// p°echod do realizovanΘho stavu</span>
<br /> mp.realize();
<br /> <span class='comment'>// zφskßnφ ovladaΦe typu ToneControl</span>
<p>┌plnß <a href='podklady/bittnerova/827/sekvence.html'>definice formßtu sekvence t≤n∙</a> je pon∞kud delÜφ, proto ji uvßdφm v externφm souboru.</p>
<h3>Poznßmka k MIDP 2.0</h3>
<p>Pokud vßs blφ₧e zajφmß MIDP 2.0, je prßv∞ v tisku Φesk² p°eklad knihy <a href='http://www.oreilly.com/catalog/j2meanut/'>J2ME v kostce</a>, kterou vydßvß Grada. Tato kniha bude obsahovat takΘ mou p°φlohu, zab²vajφcφ se prßv∞ MIDP 2.0.</p>
<h3>Odkazy, zdroje</h3>
<div class='list'>
<ul>
<li><a href='http://java.sun.com/products/j2mewtoolkit/'>J2ME Wireless Toolkit 2.1</a> - MIDP 2.0 emulßtor od firmy Sun</li>
<li><a href='http://developer.sonyericsson.com/site/global/docstools/java/p_java.jsp'>Sony Ericsson</a> - informace a emulßtory</li>
<li><a href='https://communication-market.siemens.de/portal/main.aspx?pid=1'>Siemens</a> - informace a emulßtory</li>
<li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3280' title='(36 komentß°∙)'>Interval.cz a jeho Φtenß°i</a></li>
<li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3296' title='(30 komentß°∙)'>PHP pro pokroΦilΘ - znovu t°φdy a objekty</a></li>
<li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3301' title='(24 komentß°∙)'>Kompletnφ pr∙vodce XSLT - ·vod do problematiky</a></li>
<li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3276' title='(21 komentß°∙)'>Webovß grafika podle TomßÜe BarΦφka</a></li>