Navigace

Hlavnφ menu

 

J2ME v kostce - jak na zvuk II

V p°edchozφm Φlßnku jste se seznßmili s Φßstφ Mobile Multimedia API (MMAPI) t²kajφcφ se zvuku, tentokrßt budeme pokraΦovat p°ehledem prßce se zvukem u API firmy Nokia.

Nokia UI API

API obsahujφcφ obsluhu zvuku se jmenuje Nokia UI API. Toto API by m∞ly um∞t vÜechny telefony znaΦky Nokia. N∞kterΘ u₧ ovÜem obsahujφ navic i MMAPI, kter²m jsem se zab²vala v p°edchozφm Φlßnku. MMAPI mß vφce mo₧nostφ ne₧ Nokia UI API, ale kterΘ API zvolit zßle₧φ takΘ na tom, na kter²ch vÜech telefonech mß aplikace fungovat.

Pou₧itφ t°φdy Sound z balφku com.nokia.mid.sound je celkem jednoduchΘ. Tato t°φda umo₧≥uje zahrßt t≤n danΘ frekvence a dΘlky, nebo p°ehrßt melodii ve formßtu WAV nebo RTPL (ringing tone programming language), co₧ je formßt vyzvßn∞nφ. Proto₧e ne ka₧d² telefon umφ p°ehrßt WAV a navφc je zvukov² soubor ve formßtu WAV obvykle hodn∞ velk², je lepÜφ pou₧φvat formßt RTPL, i kdy₧ umo₧≥uje hranφ pouze jednohlasΘ melodie. JakΘ formßty telefon umφ p°ehrßt, zjistφte metodou Sound.getSupportedFormats.

// zφskßnφ podporovan²ch formßt∙
int[] types = Sound.getSupportedFormats();
for(int i=0; i<types.length; i++){
    if(types[i]==Sound.FORMAT_WAV){
    // podporuje formßt WAV
    } else if (types[i]==Sound.FORMAT_TONE){
    // podporuje formßt RTPL
    }
}

Trochu nepraktickΘ je, ₧e jen n∞kterΘ emulßtory p°ehrßvajφ zvuk a obΦas i kdy₧ jej p°ehrßvajφ, je v²sledek odliÜn² od toho, co je poslΘze slyÜet z telefonu. Proto se p°i testovßnφ zvuku nespolΘhejte pouze na v²sledek dosa₧en² v emulßtoru.

P°ehrßnφ jednoho t≤nu

Telefony se mohou liÜit tφm, jakΘ t≤ny jsou schopny zahrßt. N∞kterΘ telefony mohou zvlßdat pouze frekvence odpovφdajφcφ konkrΘtnφm t≤n∙m ze stupnice a p°i pokusu nastavit jinou frekvenci vyhodφ IllegalArgumentException. T≤ny a jejich frekvence najdete v p°ipojenΘm p°ehledu.

Pokud chcete zahrßt t≤n delÜφ ne₧ dv∞ vte°iny, m∙₧e se telefon rozhodnout vßm nevyhov∞t, a to tak, ₧e nezahraje po₧adovan² t≤n, ale ani nevyhodφ ₧ßdnou v²jimku.

// Vytvo°enφ instance t°φdy Sound s danou
// frekvencφ t≤nu v Hz a dΘlkou t≤nu v milisekundßch.
// Tohle je konkrΘtn∞ 2 vte°iny trvajφcφ komornφ A

Sound sound = new Sound(440, 2000);
// P°ehrßnφ t≤nu 1x
sound.play(1);
// Nastavenφ dalÜφho t≤nu k p°ehrßnφ
sound.init(880, 1000);

P°ehrßnφ melodie

FORMAT_TONE

Pro p°ehrßnφ melodie pot°ebujeme zvukovß data p°edat t°φd∞ Sound jako pole bajt∙. P°i pou₧itφ formßtu Sound.FORMAT_TONE je nejjednoduÜÜφ mφt toto pole bajt∙ p°φmo v n∞jakΘ t°φd∞. Dßvat zvukovß data do zvlßÜtnφch soubor∙ se m∙₧e vyplatit, je-li pot°eba zvuk vym∞nit bez kompilace aplikace.

// Pole bajt∙ s melodiφ v RTPL
byte[] data = {
     (byte)0x02, (byte)0x4a, (byte)0x3a, (byte)0x40,
     (byte)0x04, (byte)0x00, (byte)0x03, (byte)0x28,
     (byte)0x00
};
// Vytvo°enφ instance t°φdy Sound
Sound sound = new Sound(data, Sound.FORMAT_TONE);
// P°ehrßnφ t≤nu 1x
sound.play(1);

Definice syntaxe RTPL je snad jeÜt∞ mΘn∞ p°ehlednß ne₧ definice syntaxe sekvence t≤n∙ pro MMAPI z p°edchozφho Φlßnku. Lze ji nalΘzt ve specifikaci Smart Messaging Specification. NaÜt∞stφ nenφ pot°eba se syntaxφ RTPL vlastnoruΦn∞ prokousat. Nokia Developer's Suite 2.0 for J2ME obsahuje konvertor pro p°evod zvuku na pole bajt∙ ve sprßvnΘm formßtu.

Audio Konvertor
Audio konvertor (plnß velikost, cca 40 kB)
  • Vstupnφ formßty:
    • MIDI - net°eba p°edstavovat
    • RTXML - XML formßt vyzvßn∞nφ (ringing tone)
  • V²stupnφ formßty:
    • OTA - v²stup pro OTA stahovßnφ vyzvßn∞nφ
    • pole bajt∙ - formßt pro vlo₧enφ do JavovΘho k≤du (tento formßt vßs bude asi nejvφc zajφmat)
    • RTXML - XML formßt vyzvßn∞nφ (ringing tone), tento formßt se m∙₧e hodit, mßte-li melodii v MIDI formßtu a chcete-li ji jeÜt∞ upravit

Formßt RTXML je velmi jednoduch² a hodφ se na psanφ vlastnφch melodiφ, pokud umφte noty. Bohu₧el jsem k tomuto formßtu nenaÜla ₧ßdnΘ dtd, tak₧e pokud budete chtφt napsat n∞jakou komplikovan∞jÜφ melodii a nebudete v hledßnφ specifikace RTXML ·sp∞Ün∞jÜφ, nezbyde vßm, ne₧ pou₧φt n∞jak² jin² editor melodie a pak se zp∞tn∞ podφvat, jak se to dalo napsat p°φmo v RTXML.

<!-- Prvnφ t°i t≤ny pφsniΦky OvΦßci Φtverßci -->
<ringing-tone name="">
   <!-- loop-value je poΦet opakovßnφ melodie -->
   <pattern id="A" loop-value="0">
      <!-- tempo melodie -->
      <tempo value="100"/>
      <!-- definuje v²Üku not, kterΘ za tφmto elementem nßsledujφ,
      nap°. je-li hodnota 1, pak nßsledujφcφ noty
      le₧φ v prvnφ oktßv∞ ap. -->

      <scale value="1"/>
      <!-- Φtvr¥ovß nota G1 -->
      <note value="G" duration="1/4"/>
      <!-- Φtvr¥ovß nota H1 (v anglicky mluvφcφch
      zemφch naz²vajφ notu H pφsmenem B) -->

      <note value="B" duration="1/4"/>
      <!-- nßsledujφcφ noty jsou z druhΘ oktßvy -->
      <scale value="2"/>
      <!-- p∙lovß nota D2 -->
      <note value="D" duration="1/2"/>
   </pattern>
</ringing-tone>

DΘlky not mohou b²t pouze zlomky mocnin dvojky, nejv∞tÜφ mo₧nß dΘlka je 1. K not∞ lze p°idat atribut specifier=".", kter² notu prodlu₧uje o polovinu jejφ dΘlky.

FORMAT_WAV

Pro p°ehrßvßnφ zvuku ve formßtu WAV je nejsnadn∞jÜφ mφt tento zvuk v samostatnΘm souboru. Formßt WAV je elektronickou verzφ libovolnΘho audio zßznamu, tak₧e s nφm jde vytvo°it komplexn∞jÜφ zvuky ne₧ pomocφ t≤novΘho formßtu. Jak jsem vÜak uvedla d°φve, jsou zvukovΘ soubory v tomto formßtu obvykle p°φliÜ velkΘ, tak₧e v mobilnφch aplikacφch jej lze pou₧φt pouze pro kratiΦkΘ zvukovΘ vzorky.

try{
   // otev°enφ vstupnφho proudu ze souboru 1.wav,
   // kter² je umφst∞n v ko°enφ JAR souboru

   InputStream is =
      this.getClass().getResourceAsStream("/1.wav");
   byte[] b = new byte[500];
   // naΦtenφ maximßln∞ 500 bajt∙ ze vstupnφho proudu
   // do pole b

   int i = is.read(b);
   // je-li i==500, je mo₧nΘ, ₧e zvukov² soubor nebyl naΦten² cel²
   // a Φtenφ je pot°eba opakovat v n∞jakΘm cyklu ...

   Sound sound = new Sound(b, Sound.FORMAT_WAV);
   sound.play(1);
} catch (Exception e){
   e.printStackTrace();
}

DalÜφ mo₧nosti NokiaUI API

Nastavenφ hlasitosti

Hlasitost zvuku se nastavuje metodou setGain(int hlasitost). Parametr "hlasitost" je Φφslo od 0 do 255, p°iΦem₧ 0 znamenß ticho a 255 nejv∞tÜφ mo₧nou hlasitost, kterou za°φzenφ dokß₧e dosßhnout.

Metoda getGain() vracφ aktußlnφ nastavenou hlasitost. Pokud jeÜt∞ nebyla volßna metoda setGain(int hlasitost), m∙₧e se stßt, ₧e implementace Javy nenφ schopna zjistit aktußlnφ hlasitost. V tom p°φpad∞ vrßtφ volßnφ metody getGain() hodnotu -1.

Zßrove≥ hranΘ zvuky

N∞kdy se v aplikaci m∙₧e hodit p°ehrßvat vφce zvuk∙ zßrove≥, nap°φklad u hry b∞₧φ na pozadφ stßle dokola jedna melodie, do kterΘ obΦas zaznφ specißlnφ zvukov² efekt. Kolik zvuk∙ konkrΘtnφ telefon umφ p°ehrßt, lze zjistit volßnφm metody static int getConcurrentSoundCount(int typMedia). Pokud telefon neumφ zßrove≥ p°ehrßvat vφce ne₧ jednu melodii, je nejjist∞jÜφ p°ed p°ehrßnφm specißlnφho efektu zastavit melodii na pozadφ metodou stop(), p°ehrßt specißlnφ efekt a po jeho skonΦenφ (zjistφ se pomocφ zaregistrovanΘho posluchaΦe) op∞t pokraΦovat v p°ehrßvßnφ melodie na pozadφ metodou resume().

PosluchaΦ zvukov²ch udßlostφ

Pro prßci se zvukem se m∙₧e hodit v∞d∞t, v jakΘm stavu se jakß zvukovß ukßzka nachßzφ. Pokud nap°φklad chceme v aplikaci na pozadφ neustßle pouÜt∞t dokola jednu zvukovou ukßzku, zaregistrujeme si na ni posluchaΦe a p°i skonΦenφ jejφho p°ehrßvßnφ ji spustφme znovu. PosluchaΦe si vytvo°φme implementacφ rozhranφ SoundListener a zaregistrujeme metodou setSoundListener(SoundListener posluchac). Jeden zvuk m∙₧e mφt nastavenΘho pouze jednoho posluchaΦe, co₧ ovÜem niΦemu nevadφ. Naopak jeden posluchaΦ m∙₧e d∞lat posluchaΦe vÜem zvuk∙m, kterΘ v aplikaci pou₧φvßme.

public class MySoundListener implements SoundListener{
   /*
      sound - instance t°φdy Sound, kde nastala udßlost
      event - udßlost, kterß nastala
   */
   public void soundStateChanged(Sound sound, int event) {
      // zde se provede obsluha udßlosti
   }
}

Udßlosti, kterΘ mohou nastat, definuje t°φda Sound jako konstanty:

  • SOUND_PLAYING - zvukovß ukßzka hraje
  • SOUND_STOPPED - p°ehrßvßnφ zvukovΘ ukßzky je zastaveno, v tomto stavu se zvuk nachßzφ po jeho vytvo°enφ, dokud jeÜt∞ nebyl spuÜt∞n
  • SOUND_UNINITIALIZED - zvukovß ukßzka se nep°ehrßvß a navφc u₧ byly uvoln∞ny vÜechny pot°ebnΘ zdroje volßnφm metody release()

Pokud u₧ zvuk nebude dßle pou₧φvßn, m∞ly by se alokovanΘ zdroje uvolnit volßnφm metody release()

Odkazy, zdroje

  • J2ME Wireless Toolkit 2.1 - MIDP 2.0 emulßtor od firmy Sun
  • Forum Nokia - informace o telefonech znaΦky Nokia, emulßtory jednotliv²ch telefon∙ a prost°edφ Nokia Developer's Suite
Bittnerovß, Lucie Rut (9. 6. 2004)
programßtor û analytik Amaio Technologies