J2ME v kostce - jak na zvuk III
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ß:
// 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:
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Θ:
// 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
:
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:
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. Parametropakovat
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.
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