Untitled - Vitajte na stránkach www.einsty.hostujem.sk
Untitled - Vitajte na stránkach www.einsty.hostujem.sk
Untitled - Vitajte na stránkach www.einsty.hostujem.sk
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
P R O G R A M U J E M E<br />
Delfinárium / 14. èas : Prehrávanie súborov MP3 I.<br />
Mnohí z vás už zrejme premýš¾ali <strong>na</strong>d tým, že si <strong>na</strong>píšu vlastný<br />
prehrávaè MP3 alebo si aspoò vy<strong>sk</strong>úšajú možnosti prehrávania<br />
súborov MP3 v Delphi. Žia¾, s Delphi sa (zatia¾) nedodáva<br />
nijaký komponent, ktorý by dokázal „empétrojky“ prehráva<br />
, a tak bude potrebné poobzera sa <strong>na</strong> internete. Pokia¾<br />
ste vášnivými zástancami Pascalu, zrejme budete <strong>sk</strong>lamaní,<br />
keï v závere svojho pátrania po webe zistíte, že azda jediným<br />
jazykom, ktorý sa používa <strong>na</strong> písanie MP3 dekodérov, je<br />
C/C++ (nestretol som sa so žiadnym dekodérom, ktorý by bol<br />
<strong>na</strong>písaný v inom programovacom jazyku). Dokonca aj komponenty<br />
pre Delphi sú implementované ako knižnice DLL,<br />
<strong>na</strong>písané v C/C++, z ktorých komponent Delphi importuje<br />
funkcie a následne ich volá. Hoci sa tieto komponenty používajú<br />
pomerne ¾ahko, nemali by ste oèakáva , že pomocou<br />
nich <strong>na</strong>píšete nový WinAmp èi Sonique. Nezabúdajte, že problematika<br />
prehrávania súborov MP3 je ve¾mi komplexná, dekodéry<br />
MP3 neraz pracujú sa úrovni strojového kódu, využívajúc<br />
inštrukcie MMX èi 3DNow! Je však celkom pravdepodobné, že<br />
v èase, keï budete tento materiál èíta , už budú k dispozícii<br />
komponenty schopné využi výhody aj týchto inštrukcií.<br />
Komponent, ktorý vám tentoraz predstavíme, patrí medzi<br />
tie, ktoré sa dajú relatívne ¾ahko zvládnu . K dispozícii je <strong>na</strong><br />
serveri <strong>www</strong>.eldos.org. Okrem zdrojových súborov komponentu<br />
Delphi nájdete v archíve aj zdrojové súbory dekodérov,<br />
<strong>na</strong>písané v jazyku C++ (tie ve¾mi nevyužijete). Po rozbalení<br />
budete možno prekvapení, že nevidíte nijaké knižnice DLL.<br />
Autori totiž použili malý trik a príponu knižnice DLL (ktorá je<br />
vlastne dekodérom) zmenili <strong>na</strong> ESP (funkcii LoadLibrary totiž<br />
neprekáža, ak je prípo<strong>na</strong> súboru iná ako DLL). Súèas ou distribúcie<br />
sú tri knižnice DLL: prvou je MPEG dekodér ElAMP, s<br />
ktorým budeme pracova (súbor ELAMP.ESP). Druhou je rozhranie<br />
pre Windows Media Audio Decoder Interface (súbor<br />
WMAMP.ESP) a tre ou knižnica <strong>na</strong> prehrávanie súborov WAV<br />
(súbor WAVMP.ESP). Celý systém je podobne ako WinAmp<br />
postavený <strong>na</strong> modulárnom princípe. V praxi to z<strong>na</strong>mená, že<br />
dokonca aj poèas behu programu je možné zavies a spusti<br />
¾ubovo¾ný dekodér (samozrejme, ten musí spåòa urèité kritériá<br />
a musí by <strong>na</strong>písaný tak, aby dokázal s Delphi komponentom<br />
komunikova ). Žia¾, poèas dnešnej MP3 púte túto možnos<br />
nevyužijeme, pretože momentálne je pre nás zaujímavý<br />
iba jeden jediný dekodér: ElAMP.<br />
Po <strong>sk</strong>onèení inštalácie vám <strong>na</strong> palete komponentov pribudne<br />
komponent TElPlayerMan. Okrem toho sa v archíve<br />
<strong>na</strong>chádza aj komponent TSlider, <strong>na</strong>inštalujte si aj ten.<br />
Budeme ho totiž používa <strong>na</strong>miesto komponentu TTrack-<br />
Bar, ktorý sa <strong>na</strong> multimediálne úèely ve¾mi nehodí (ne<strong>sk</strong>ôr<br />
si povieme, preèo je to tak). Komponent TElPlayerMan plní<br />
úlohu akéhosi ma<strong>na</strong>žéra dekodérov. Jeho <strong>na</strong>jdôležitejšou<br />
vlastnos ou je vlastnos Players, ktorá obsahuje zoz<strong>na</strong>m<br />
všetkých prehrávaèov (èiže dekodérov). Ako som už spomenul,<br />
s komponentom sa dodávajú tri dekodéry, my<br />
však budeme hovori iba o dekodéri MP3.<br />
Chcel by som ešte upozorni <strong>na</strong> to, že v èase písania<br />
tohto èlánku mal ElAMP problémy s prehrávaním súborov<br />
s premenlivým bitrate. Dekódoval ich síce správne, ale<br />
vlastnosti Size a Position nevracali korektné hodnoty.<br />
NÁŠ PRVÝ PREHRÁVAÈ MP3. Predpokladám,<br />
že by ste si èo <strong>na</strong>j<strong>sk</strong>ôr chceli vy<strong>sk</strong>úša , ako vyzerá prehrávanie<br />
súborov MP3 v praxi. Napíšeme si teda jednoduchý<br />
prehrávaè MP3, ktorý ne<strong>sk</strong>ôr zdoko<strong>na</strong>líme.<br />
Základom všetkého je administrátor dekodérov, <strong>na</strong>zvaný<br />
TElPlayerMan. Pridáme ho <strong>na</strong> formulár a otvoríme vlastnos<br />
Players. Ako som už spomí<strong>na</strong>l, táto vlastnos obsahuje zoz<strong>na</strong>m<br />
všetkých dekodérov, ktoré sú v tomto komponente<br />
zaregistrované. Stlaèíme tlaèidlo Add, èím do zoz<strong>na</strong>mu pridáme<br />
nový dekódovací modul. Vyplníme vlastnos Path-<br />
ToDLL, prièom uvedieme nielen cestu, ale aj názov súboru:<br />
ELAMP.ESP. Potom <strong>na</strong>stavíme vlastnos Initialized <strong>na</strong> true.<br />
Pokia¾ komponent nezahlási chybu, máme <strong>sk</strong>oro vyhrané,<br />
pretože dekodér MPEG sa úspešne zinicializoval. Nastavme<br />
vlastnos Initialized spä <strong>na</strong> false a poïme si trochu pocvièi<br />
prsty <strong>na</strong>písaním krátkeho kódu.<br />
Na hlavný formulár pridáme dva komponenty TButton,<br />
ktoré <strong>na</strong>zveme Play a Stop. Po stlaèení prvého tlaèidla sa<br />
vykoná <strong>na</strong>sledujúca procedúra:<br />
procedure TForm1.PlayClick(Sender: TObject);<br />
begin<br />
MP3.Players[0].Init;<br />
OpenDialog1.Filter := MP3.Players[0].ModuleName +<br />
‘|’ + MP3.Players[0].Extensions;<br />
if not OpenDialog1.Execute then exit;<br />
MP3.Players[0].InputName:=OpenDialog1.FileName;<br />
MP3.Players[0].Open;<br />
MP3.Players[0].InitStream;<br />
MP3.Players[0].Play;<br />
end;<br />
Prvý príkaz slúži <strong>na</strong> inicializáciu dekodéra (vykoná v podstate<br />
to isté, èo sme vyko<strong>na</strong>li my v Object Inspectore <strong>na</strong>stavením<br />
vlastnosti Initialized <strong>na</strong> true). Potom sa zobrazí dialógové<br />
okno <strong>na</strong> otvorenie súboru, ktoré využíva vlastnos Extensions<br />
komponentu TElPlayer. Každý dekodér totiž vie poda<br />
informáciu o tom, aké typy súborov dokáže prehráva , vïaka<br />
èomu odpadá práca s vytváraním filtra súborov. Keï používate¾<br />
vyberie požadovaný súbor, procedúra <strong>na</strong>staví vlastnos<br />
InputName, èo je vlastne názov súboru MP3, ktorý sa bude<br />
prehráva . Tento súbor sa otvorí pomocou metódy Open a<br />
zinicializuje prostredníctvom metódy InitStream. Predpokladám,<br />
že funkciu metódy Play nie je potrebné objasòova .<br />
Samozrejme, <strong>sk</strong>ladbu musíme vedie aj zastavi :<br />
procedure TForm1.StopClick(Sender: TObject);<br />
begin<br />
MP3.Players[0].Stop;<br />
end;<br />
Po ukonèení práce s programom by sme mali prehrávaè<br />
odstráni z pamäte:<br />
procedure TForm1.FormClose(Sender: TObject; var<br />
Action: TCloseAction);<br />
begin<br />
MP3.Players[0].Deinit;<br />
end;<br />
Žia¾, v dokumentácii sa nepíše, èi je potrebné vola<br />
metódu Deinit pred ukonèením programu, to by mal totiž<br />
komponent vyko<strong>na</strong> sám. Každopádne v ukážkovom programe,<br />
ktorý sa s komponentom dodáva, je táto metóda<br />
volaná tesne pred uzavretím hlavného formulára.<br />
Pomerne dôležitú úlohu pri prehrávaní súborov MP3 plnia<br />
vlastnosti BufferSize a BuffersCount (myslím, že ich funkciu<br />
nie je potrebné vysvet¾ova ). Spravidla platí, že èím viac bufferov<br />
alokujete a èím sú tieto buffery väèšie, tým je menšia<br />
pravdepodobnos „zadrhávania sa“ poèas prehrávania <strong>sk</strong>ladby.<br />
Na druhej strane sa však zvyšuje doba, ktorá je potrebná<br />
<strong>na</strong> spracovanie príkazov typu Stop. Optimálnu hodnotu pre<br />
váš stroj si musíte urèi experimentálnou metódou. Ak máte<br />
chu , môžete prehrávaè upravi tak, aby mohol poèet a ve¾kos<br />
vyrovnávacích pamätí <strong>na</strong>stavova používate¾.<br />
ZDOKONALENÝ PREHRÁVAÈ MP3. Náš ïalší<br />
prehrávaè MP3 už bude o nieèo vyspelejší. Zložený bude<br />
z dvoch hlavných okien: playlist editora a samotného prehrávaèa.<br />
Vytvorme teda novú aplikáciu, do ktorej pridáme<br />
dve okná: prvé <strong>na</strong>zveme PlayerWnd a druhé PlayListWnd.<br />
Vlastnos BorderStyle prvého formulára <strong>na</strong>stavíme <strong>na</strong> bsDialog,<br />
pretože rozmery hlavného ok<strong>na</strong> budú fixné. To neplatí<br />
pre druhý formulár, ktorého rozmery sa síce môžu meni ,<br />
nesmieme však používate¾ovi umožni tento formulár minimalizova<br />
èi maximalizova . Preto otvoríme vlastnos Border-<br />
Icons a položky biMaximize a biMinimize <strong>na</strong>stavíme <strong>na</strong> false.<br />
Mimochodom, hoci som v predchádzajúcich èlánkoch nieko¾kokrát<br />
zdôraznil, že by sme mali v programoch z dôvodu<br />
úspory pamäte formuláre vytvára ruène, tentoraz to neurobíme.<br />
Dôvod je jednoduchý: obe okná sa budú používa tak<br />
èasto, že jednoducho nemá zmysel vytvára ich poèas behu<br />
programu. Samozrejme, pokia¾ sa ne<strong>sk</strong>ôr rozhodneme program<br />
rozšíri o ïalšie okná, tie by už mali by vytvárané ruène<br />
(teda volaním konštruktora formulára).<br />
Keïže prehrávaè je priamo závislý od playlist editora, zaèneme<br />
<strong>na</strong>jprv posledne menovaným oknom. Na hlavný formulár<br />
(teda <strong>na</strong> okno PlayerWnd) pridáme tlaèidlo, ktoré <strong>na</strong>zveme<br />
PlayEdit. Istotne ste sa dovtípili, že úlohou tohto tlaèidla bude<br />
vyvola playlist editor. Ïalej je potrebné <strong>na</strong>stavi vlastnos Position<br />
<strong>na</strong> poDesigned, pretože playlist editor sa po stlaèení<br />
tlaèidla zobrazí tesne pod oknom prehrávaèa:<br />
procedure TPlayerWnd.PlayEditClick(Sender: TObject);<br />
begin<br />
PlayListWnd.Top:=PlayerWnd.Top+PlayerWnd.Height;<br />
PlayListWnd.Left:=PlayerWnd.Left;<br />
PlayListWnd.Width:=PlayerWnd.Width;<br />
PlayListWnd.Show;<br />
end;<br />
Tento kód pracuje <strong>na</strong> ve¾mi jednoduchom princípe: Y-ová<br />
súradnica miesta, kde sa má playlist editor zobrazi , je definovaná<br />
ako súèet „top“ súradnice hlavného ok<strong>na</strong> a jeho výšky.<br />
Podobne ako vo WinAmpe aj tu sú obe okná rov<strong>na</strong>ko vzdialené<br />
od ¾avého okraja obrazovky, preto majú obe vlastnosti Left<br />
rov<strong>na</strong>kú hodnotu. Okrem toho majú okná aj rov<strong>na</strong>kú šírku, èo<br />
sme dosiahli pomocou predposledného riadka (ako som však<br />
spomenul, ve¾kos playlist editora je možné zmeni ).<br />
Samozrejme, do playlist editora sa musia da umiestni aj<br />
nejaké <strong>sk</strong>ladby. Ich poèet nám bude zobrazova komponent<br />
TStatusBar, ktorého vlastnos SimplePanel <strong>na</strong>stavíme <strong>na</strong> true.<br />
Potom pridáme komponent TPanel, ktorý bude obsahova<br />
dve tlaèidlá: jedno som <strong>na</strong>zval Pridaj (bude slúži <strong>na</strong> pridanie<br />
nového súboru do playlistu) a Vymaz, ktoré súbor z playlistu<br />
vymaže. Zoz<strong>na</strong>m súborov MP3 bude zobrazova komponent<br />
TlistBox, <strong>na</strong>zvaný PlayList. Vlastnos Align tohto komponentu<br />
<strong>na</strong>stavíme <strong>na</strong> alClient.<br />
Na chví¾u teraz odboèíme a otvoríme si formulár Player-<br />
Wnd. Pridáme komponent TEIPlayerMan, ktorý <strong>na</strong>zveme<br />
PlayerMan. Vytvoríme nový prehrávaè a vyplníme vlastnos<br />
PathToDLL (<strong>na</strong>stavíme ju <strong>na</strong> dekodér ELAMP.ESP). Aby sme ku<br />
komponentu TEIPlayer nemuseli pristupova pomocou vlastnosti<br />
Players komponentu TEIPlayerMan, upravíme deklaráciu<br />
hlavného formulára a vytvoríme premennú s názvom Player:<br />
private<br />
{ Private declarations }<br />
public<br />
Player : TElPlayer;<br />
{ Public declarations }<br />
end;<br />
Aby sme mohli túto premennú používa , musíme urobi<br />
jednu jednoduchú operáciu v obsluhe udalosti On-<br />
Show hlavného formulára:<br />
procedure TPlayerWnd.FormShow(Sender: TObject);<br />
begin<br />
Player:=PlayerMan.Players[0];<br />
Player.Init;<br />
end;<br />
Tento zápis prekladaèu povie, že premenná Player je zhodná<br />
s nultým dekodérom obsiahnutým vo vlastnosti Players.<br />
Inými slovami, to, èo robíme s touto premennou, akoby<br />
sme robili s prehrávaèom (dekodérom). Všetky operácie teda<br />
budeme vykonáva prostredníctvom premennej Player.<br />
Teraz sa možno pýtate, preèo sme prerušili návrh playlist<br />
editora, keï ten ešte nie je hotový. Musíme predsa ešte<br />
prida komponent TOpenDialog, ktorý nám umožní prida<br />
do playlistu súbory. Nuž, práve s komponentom TOpen-<br />
Dialog toto prerušenie súvisí: pomocou premennej Player<br />
totiž budeme vedie zisti typy súborov, ktoré dokáže dekodér<br />
prehráva , a následne budeme vedie pod¾a toho <strong>na</strong>stavi<br />
vlastnos Filter komponentu TOpenDialog.<br />
Vrá me sa však spä k návrhu ok<strong>na</strong> PlayListWnd a pridajme<br />
komponent TOpenDialog, ktorý bude nies meno<br />
OpenDlg. Obslužná ruti<strong>na</strong> udalosti OnClick tlaèidla Pridaj<br />
bude vyzera takto:<br />
procedure TPlayListWnd.PridajClick(Sender: TObject);<br />
begin<br />
with PlayerWnd do<br />
OpenDlg.Filter := Player.ModuleName + ‘|’ +<br />
Player.Extensions;<br />
if not OpenDlg.Execute then exit;<br />
PlayList.Items.Add(OpenDlg.FileName);<br />
StatusBar.SimpleText:='Poèet <strong>sk</strong>ladieb: ' +<br />
IntToStr(PlayList.Items.Count);<br />
end;<br />
Samozrejme, nesmieme zabudnú <strong>na</strong> tlaèidlo Vymaz, ktoré<br />
má za úlohu vymazanie súboru z playlistu:<br />
12/2001 PC REVUE 141