J2ME v kostce – jak na zvuk 3.

12. srpna 2004

V předchozích článcích jsme se postupně probrali univerzálním rozhraním pro manipulaci se zvukem v mobilních telefonech Mobile Media API a proprietárním rozhraním firmy Nokia. V tomto článku stejným způsobem projdeme proprietární řešení API dalších výrobců, firem Siemens, Samsung a Motorola.

Siemens

Jak jsem uvedla v prvním článku o zvuku, většina telefonů značky Siemens obsahuje část rozhraní Mobile Media API (MMAPI) řešící práci se zvukem, jen toto rozhraní schovává do jiných balíků, a to com.siemens.mp.media a com.siemens.mp.media.control. Kromě tohoto rozhraní obsahují pro práci se zvukem všechny telefony značky Siemens ještě tři třídy v balíku com.siemens.mp.game. Jsou to třídy Sound, Melody a MelodyComposer. Tyto třídy jsou nezbytně nutné k přehrání zvuku na starších modelech telefonů značky Siemens, jako jsou SL45i a M50, ale měly by fungovat na všech modelech.

Přehrání jednoho tónu

K přehrání jednoho tónu dané frekvence a délky slouží třída Sound. Tato třída má jedinou metodu, která je statická:

// Přehrání tónu 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.playTone(440, 2000);

Přehrání melodie

Třída MelodyComposer je určena ke kompozici skladby. Za tím účelem definuje jako konstanty výšky tónů od A0 do do A4 (A0 odpovídá našemu tónu malé A, tedy tónu s frekvencí 220 Hz, který leží v houslovém klíči na druhé pomocné lince pod notovou osnovou).

  • TONE_A0, TONE_AIS0 ... TONE_GIS4, TONE_A4

Dále obsahuje tónové konstanty se speciálním významem:

  • TONE_PAUSE – pomlka
  • TONE_REPEAT – opakuj od začátku až sem n-krát (n je parametr zadaný jako délka tónu, musí být přirozené číslo)
  • TONE_REPEV – opakuj od začátku až sem stále dokola
  • TONE_REPON – opakuj od začátku až sem n-krát a pak pokračuj dál
  • TONE_MARK – nastavení značky
  • TONE_REPEAT_MARK – opakuj od nejbližší předchozí značky n-krát
  • TONE_REPEV_MARK – opakuj od nejbližší předchozí značky stále dokola
  • TONE_REPON_MARK – opakuj od nejbližší předchozí značky n-krát a pak pokračuj dál

Další konstanty určují délku tónů:

  • TONELENGTH_1_1 – celá nota
  • TONELENGTH_1_2 – půlová nota
  • TONELENGTH_1_4 – čtvrťová nota
  • TONELENGTH_1_8 – osminová nota
  • TONELENGTH_1_16 – šestnáctinová nota
  • TONELENGTH_1_32 – dvaatřicetinová nota
  • TONELENGTH_1_64 – čtyřiašedesátinová nota
  • TONELENGTH_DOTTED_1_1 – celá nota s tečkou
  • TONELENGTH_DOTTED_1_2 – půlová nota s tečkou
  • TONELENGTH_DOTTED_1_4 – čtvrťová nota s tečkou
  • TONELENGTH_DOTTED_1_8 – osminová nota s tečkou
  • TONELENGTH_DOTTED_1_16 – šestnáctinová nota s tečkou
  • TONELENGTH_DOTTED_1_32 – dvaatřicetinová nota s tečkou
  • TONELENGTH_DOTTED_1_64 – čtyřiašedesátinová nota s tečkou

A po spoustě konstant konečně nějaká ukázka:

// Definice posloupnosti tónů zvukové ukázky
int[] tones = {
  MelodyComposer.TONE_G1, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_H1, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_D2, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_PAUSE, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_REPON, 2,
  MelodyComposer.TONE_MARK, 0,
  MelodyComposer.TONE_H1, MelodyComposer.TONELENGTH_1_4,
  MelodyComposer.TONE_H1, MelodyComposer.TONELENGTH_1_4,
  MelodyComposer.TONE_A1, MelodyComposer.TONELENGTH_1_4,
  MelodyComposer.TONE_H1, MelodyComposer.TONELENGTH_1_4,
  MelodyComposer.TONE_C2, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_A1, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_REPON_MARK, 2,
  MelodyComposer.TONE_H1, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_A1, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_G1, MelodyComposer.TONELENGTH_1_2,
  MelodyComposer.TONE_PAUSE, MelodyComposer.TONELENGTH_1_2,};

Přehrání ukázky je velmi jednoduché:

// Vytvoření instance třídy MelodyComposer s nastavenou
// melodií a tempem 120 úderů za minutu

MelodyComposer composer = new MelodyComposer(tones, 120);
// Získání instance třídy Melody
Melody melody = composer.getMelody();
// Spuštění přehrávání melodie. Metoda play neblokuje běh aplikace,
přehrávání probíhá na pozadí.

melody.play();

Přehrávání melodie lze zastavit příkazem melody.stop(). Pokud začnete přehrávat novou zvukovou ukázku v době, kdy ještě hraje předchozí zvuková ukázka, přehrávání staré ukázky se ihned ukončí a bude spuštěna ukázka nová.

Třída Melody obsahuje pouze metody play() a stop(), nenabízí žádnou možnost jak zjistit, zda zvuková ukázka ještě hraje nebo už skončila. Chcete-li po dobu běhu aplikace hrát stále dokola nějakou melodii, ukončete ji tónem TONE_REPEV.

Takto se vymění melodie v již existující instanci třídy MelodyComposer:

// Vymazání aktuální melodie
composer.resetMelody();
// Nastavení nové melodie; lze provést pouze po jednotlivých notách
try{
   for(int i=0; i<tones.length; i++){
      composer.appendNote(tones[i], tones[++i]);
   }
} catch(Exception e){
}
// Nastavení tempa
composer.setBPM(60);
// Spuštění přehrávání melodie
composer.getMelody().play();

Třída MelodyComposer obsahuje omezení na maximální délku definice melodie. Tato maximální délka se zjistí metodou maxLength(), délku aktuální ukázky vrací metoda length().

To jsou všechna kouzla, která se dají s třídami Sound, Melody a MelodyComposer provozovat. Žádné vymoženosti, jako posluchače událostí nebo spouštění zvukových ukázek ve formátech jako například MIDI či WAV, zde nenajdete.

Samsung

Práce se zvukem na telefonech značky Samsung je snad ještě jednodušší. Vše zařizuje třída com.samsung.util.AudioClip. Tato třída umožňuje zjistit, zda je přehrávání zvuku implementováno, a pokud ano, lze ovládat přehrávání zvukové ukázky následujícími metodami:

  • play(int pocetOpakovani, int hlasitost) – spustí přehrávání, počet opakování ukázky může být číslo od 0 do 255 a hlasitost číslo od 0 do 5
  • pause() – přeruší přehrávání
  • resume() – pokračuje v přehrávání z místa, kde byla ukázka přerušena
  • stop() – ukončí přehrávání ukázky a uvolní všechny zdroje

Samsung neumí přehrávat více zvukových ukázek zároveň. Pokud v okamžiku spuštění zvukové ukázky už nějaká hraje, je tato hrající ukázka nahrazena novou.

Pro specifikaci typu přehrávaného zvuku obsahuje třída AudioClip číselné konstanty:

  • TYPE_MMF – hodnota 1
  • TYPE_MP3 – hodnota 2
  • TYPE_MIDI – hodnota 3

V API emulátoru ale třída AudioClip tyto konstanty neobsahuje, proto je jistější místo nich použít čísla. Také zatím nemá smysl používat jiný typ zvukové ukázky než MMF (formát vyzvánění na telefony Samsung), protože zatím jiné typy podporovány nejsou, vývojáři si konstanty nejspíš připravili pro případ, že by se jim chtělo přehrávání MP3 a MIDI implementovat v Javě někdy v budoucnosti.

Přehrání zvukové ukázky vypadá takto:

// Kontrola, zda je přehrávání zvuku implementováno
if(AudioClip.isSupported()) {
   // Vytvoření instance třídy AudioClip s nastaveným
   typem ukázky a cestou k ukázce

   AudioClip clip = new AudioClip(1, „/ukazka.mmf“);
   // Spuštění ukázky jedenkrát s maximální hlasitostí
   clip.play(1, 5);
}

Motorola

Některé telefony značky Motorola už obsahují implementaci MIDP 2.0 (V300, V400, V500, V600), takže u nich se k přehrávání zvuku použije MMAPI. Některé z těch telefonů, které obsahují pouze implementaci MIDP 1.0, mají navíc proprietární API od Motoroly, které usnadňuje vývoj her a zároveň obsahuje třídy pro přehrávání zvuku. Jsou to například telefony C370, C450, C550. Na stránkách Motocoderu najdete k jednotlivým telefonům podrobnou dokumentaci.

Třídy určené k přehrávání zvuku se nacházejí v balíku com.motorola.game a jsou dvě. Třída BackgroundMusic reprezentuje hudbu na pozadí aplikace a třída SoundEffect reprezentuje zvukový efekt ve hře. S těmito třídami se dále pracuje s použitím metod třídy GameScreen:

  • boolean soundEffectsSupported() – vrátí „true“, pokud je podporováno přehrávání zvukových efektů
  • boolean backgroundMusicSupported() – vrátí „true“, pokud je podporováno přehrávání hudby na pozadí
  • int getMaxSoundsSupported() – vrátí maximální možný počet zároveň přehrávaných zvuků, které telefon zvládne
  • void playSoundEffect(SoundEffect efekt, int hlasitost, int priorita) – spustí zvukový efekt. Hlasitost a priorita mohou být od 0 do 100. Pokud by mělo zároveň hrát více efektů, než zařízení zvládá, přehraje se ten, který má nastavenou vyšší prioritu. Zvukové efekty hrají pouze tehdy, když je jejich instance třídy GameScreen zobrazena na displeji.
  • void stopAllSoundEffects() – zastaví přehrávání všech zvukových efektů (netýká se hudby na pozadí)
  • void playBackgroundMusic (BackgroundMusic zvuk, boolean opakovat) – spustí přehrávání zvuku na pozadí aplikace. Pokud už nějaký zvuk na pozadí hraje, je tímto nahrazen, je-li parametr zvuk „null“, je pouze právě přehrávaný zvuk zastaven. Parametr opakovat určuje, zda se má hrát zvuková ukázka stále dokola (true) nebo nikoli (false).

Zvuk na pozadí

Na pozadí hry nebo aplikace může být spuštěn maximálně jeden zvuk. Tento zvuk může být uložen v JAR souboru aplikace, nebo může být na serveru a aplikace si jej stáhne s použitím protokolu HTTP. Implementovaný formát je pouze MIDI 0 nebo 1.

// vytvoření vlastní třídy rozšiřující GameScreen
public class MyScreen extends GameScreen {
  public void playBackgroundMusic(){
    try{
      // Vytvoření instance třídy BackgroundMusic
      BackgroundMusic samp =
         BackgroundMusic.createBackgroundMusic(„/samp.mid“);
      // Spuštění ukázky stále dokola.
      playBackgroundMusic(samp, true);
    }catch(FileFormatNotSupportedException e){
      // Formát zvukové ukázky není podporován
    }
  }
}

Zvukový efekt se spustí analogicky jako zvuk na pozadí.

Závěrem

Tyto články o zvuku neměly ambice pokrýt úplně všechny značky telefonů, na kterých se dá potkat Java, ale mohli jste se v nich seznámit s těmi nejrozšířenějšími značkami v Čechách a přilehlém okolí. Pokud se rozhodnete uživatele nějaké aplikace obšťastnit zvukovými efekty, určitě nezapomeňte na možnost tyto efekty vypnout. Uděláte tím radost nejen školákům nudícím se na hodině matematiky.

Odkazy, zdroje

  • J2ME Wireless Toolkit – obecný emulátor od firmy Sun
  • Motocoder – stránky pro vývojáře pracující s telefony značky Motorola
  • Samsung – emulátory a další informace pro vývojáře pracující s telefony značky Samsung
  • Siemens – portál pro vývojáře pracující s telefony značky Siemens

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *