WinAmp Plug-in – 1. část - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Delphi

WinAmp Plug-in – 1. část

winamp

16. prosince 2002, 00.00 | Program WinAmp zná určitě většina čtenářů dobře a také každý den používá. My se dnes ale nebudeme zabývat programem, ale tvorbou zásuvných modulů nazývaných také jako moduly plug-in. Ty umožňují připojit další funkce přehrávače, které si může uživatel sám zvolit. Konkrétně půjde o plug-in vytvářející vizuální výstup zvukového souboru, neboli graficky upravené spektrum zvuku aktuálně přehrávané skladby.

Program WinAmp zná určitě většina čtenářů dobře a většina také každý den používá. Není se totiž čemu divit, protože software firmy Nullsoft je opravdu jedním z nerozšířenějších hudebních přehrávačů dnešního počítačového světa a i přesto je doposud distribuován jako freeware. Tzn. Kdokoliv kdo má zájem si jej může stáhnout z adresy www.winamp.com. V poslední době vyšla dokonce nová verze onoho programu, která si dokonce hravě poradí i video-soubory, čímž se snaží oslovit ještě větší skupinu uživatelů PC na platformě Windows.
My se dnes ale nebudeme zabývat programem, ale tvorbou zásuvných modulů nazývaných také jako moduly plug-in. Ty umožňují připojit další funkce přehrávače, které si může uživatel sám zvolit. Konkrétně půjde o plug-in vytvářející vizuální výstup zvukového souboru, neboli graficky upravené spektrum zvuku aktuálně přehrávané skladby.

Jak na to?

V podstatě budeme vytvářet program jako každý jiný, ale výsledný soubor nebude mít příponu EXE, ale DLL (dynamic linking library). Ten se poté zkopíruje do složky PlugIn uvnitř instalace Winampu. Spustit jej potom můžeme přímo z programu volbou Options -> Preferences -> Vizualization.
Pusťme se ale již do tvorby oné DLL. Spustíme vývojový nástroj Delphi a zvolíme menu File -> New . Zde v záložce NEW vybereme DLL a potvrdíme tlačítkem OK. Objeví se nám soubor Project1.dpr s již předem vyplněnými údaji. Dále provedeme tutéž akci ještě jednou, ale s tím rozdílem, ze ze záložky NEW vybereme FORM a opět potvrdíme OK. Nyní máme vytvořený projekt s jedním formulářem a jedním zdrojovým souborem. Zaměříme se ale na data předem vyplněná v souboru Project1.dpr. Ty nebudeme potřebovat a proto je upravíme na přibližně následující podobu:

library Project1;
uses
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
exports
winampVisGetHeader; //vysvětlím později
end.

Celý projekt uložíme do jedné složky někam na disk. Teď budeme upravovat jen zdrojový kód programu tzn. soubor unit1.pas. Nejdůležitější věcí při tvorbě knihovny DLL je znát strukturu datových typů, pomocích nichž komunikuje program s knihovnou a předá jí požadované data. Tato struktura je pevně dána programátory WinAmpu a je následující:

type
PwinampVisModule =^TwinampVisModule;
TwinampVisModule = record
description: PChar; //název plug-in, který vidí uživatel WinAmpu
hwndParent: HWND; //handle na rodičovské okno
hDllInstance: HINST;
sRate,nCh, //počet zvukových kanálů
latencyMs,
delayMs, //interval posílání dat knihově
spectrumNch, //počet požadovaných kanálů zvukového spektra
waveformNch: Integer; //počet požadovaných kanálů zvukové “vlny”
spectrumData: array[0..1,0..575]of char; //spektrální data
waveformData: array[0..1,0..575]of char; //data zvukové “vlny”
Config: procedure(this_mod:PwinampVisModule);cdecl
Init: function(this_mod:PwinampVisModule):Integer;cdecl;
Render: function(this_mod:PwinampVisModule):Integer;cdecl;
Quit: procedure(this_mod:PwinampVisModule);cdecl;
userData: Pointer;
end;

PwinampVisHeader =^TwinampVisHeader;
TwinampVisHeader = record
version: Integer;
description: PChar;
getModule: function(i:Integer):PwinampVisModule;cdecl;
end;

winampVisGetHeaderType=function:PwinampVisHeader;

Jelikož je tato struktura k samotnému vývoji nepotřebná, doporučuji si ji uložit do externího souboru např. winamp.pas, který se připojí přidáním slova winamp do jednotky uses těla programu. V tuto chvíli je taky vhodné vytvoření několika konstant, jejichž význam bude vysvětlen později:

const
hdr: TwinampVisHeader =
(version:1; //verze plug-in modulu
description:'Ukázkový Plug-in ke článku ze serveru www.builder.cz '; //název plug-inu
getModule:getModule);

fmod1: TwinampVisModule =
(description:'Osciloskop'; //název modulu
hwndParent:0;
hDllInstance:0;
sRate:0;
nCh:0;
latencyMs:0;
delayMS:25;
spectrumNch:0;
waveformNch:2; //budeme využívat 2 kanály (levý a pravý)
Config:config; //funkce config bude společná pro oba moduly
Init:init; //taktéž funkce Init a funkce Quit
Render:render1; // v této funkci se bude kreslit grafický výstup
Quit:quit);

fmod2: TwinampVisModule =
(description:'Spektrum';
hwndParent:0;
hDllInstance:0;
sRate:0;
nCh:0;
latencyMs:25;
delayMS:25;
spectrumNch:2; //výsledek bude větší hodnota z levého či pravého kanálu
waveformNch:0;
Config:config; //opět stejné funkce jako v modulu 1
Init:init;
Render:render2;
Quit:quit);

Dále musíme také deklarovat a implementovat několik potřebných funkcí které nám zajistí správné připojení knihovny a správný chod plug-inu:

function winampVisGetHeader:PwinampVisHeader;cdecl;export;
function getModule(which:Integer):PwinampVisModule;cdecl;
procedure config(this_mod:PwinampVisModule);cdecl;
function init(this_mod:PwinampVisModule):Integer;cdecl;
function render1(this_mod:PwinampVisModule):Integer;cdecl;
function render2(this_mod:PwinampVisModule):Integer;cdecl;
procedure quit(this_mod:PwinampVisModule);cdecl;

Funkce winampVisGetHeader slouží ke komunikaci modulu se samotným winampem, který ji také sám volá. Proto musí být deklarovaná jako export a cdecl a uvedena v tele souboru Project1.dpr v sekci exports. Deklarace export se týkají volání funkcí v 16-bit aplikacích a deklarace cdecl se používá v případech, kdy voláme funkce, které jsou napsány v C nebo C++ a to WinAmp zcela jistě je.

function winampVisGetHeader:PwinampVisHeader;
begin
Result:=@hdr; //předává winampu adresu hlavičky našeho plug-inu
end;

Funkce getModule nám vybírá který modul si uživatel při spouštění plug-inu zvolil. V našem příkladu budeme používat 2 moduly. Jeden bude mít výstup jako spektrum a druhý jako “zvuková vlna”. Parametr which určuje který modul byl vybrán a je to vlastně index vybraného prvku v ComboBoxu, tzn. první modul má hodnotu 0.

function getModule(which:Integer):PwinampVisModule;
begin
case which of
0:Result:=@fmod1;
1:Result:=@fmod2;
else
Result:=nil;
end;
end;

Procedura config má v podstatě stejný význam jako např. nastavení u spořiče obrazovky. U vizualizačních plug-inech má většinou spíš funkcí zobrazení nápovědy, ale její skutečný význam je v donastavení určitých parametru plug-inu podle požadavků koncového uživatele. My zde pouze zobrazíme zprávu pro uživatele pomocí funkce MessageBox.
Funkce Init a Quit jsou stejného významu jako metody formuláře OnCreate a OnDestroy. Funkce Init se vola při spuštění plug-inu a quit se volá při uzavření plug-inu. Je velmi důležité aby funkce Init obsahovala min. příkaz k vytvoření a zviditelnění formuláře, jinak nebude náš program vidět. Funkce Quit musí naopak obsahovat příkaz Form1.close, který uvolní z paměti vytvořené objekty a pošle programu zprávu, že byl plug-in uzavřen. Tělo funkce Init:

Application.CreateForm(TForm1,Form1);
Form1.Show;

Nakonec jsem si nechal funkce render1 a render2. Ty zajišťují kreslení požadovaného grafického výstupu. Jejich volání řídí sám winamp a jejich četnost se řídí nastavením parametru delayMS každého modulu zvlášť. Parametr udává dobu v milisekundách, po které je funkce render1 čí render2 volána. Optimální dobou je asi 25ms. Při zvětšení je již vidět výrazné zpomalení a nesoulad s právě vnímaným zvukovým vjemem. Naopak při době kratší než 25ms je výstup moc rychlý a špatně zřetelný. Vše ale samozřejmě závisí na vzhledu výstupu. Pro začátek nám bude stačit když vypíšeme pozdrav na obrazovku:

function render1(this_mod:PwinampVisModule):Integer;
var bmp:TBitmap;
begin
bmp:=TBitmap.create;
bmp.width:=200;
bmp.height:=100;
bmp.canvas.textout(0,0,‘Vystup plug-inu v modu 1‘);
form1.canvas.draw(0,0,bmp);
bmp.free;
Result:=0; //vraci 0 pokud vse probehlo spravne
end;

Podobně bude vypadat funkce render2 , kterou zde již neuvádím. Nyní jsme již udělali všechno potřebné k tomu, abychom mohli náš projekt přeložit. Uděláme to jako kdybychom psali normální program (např. klávesou F9). Namísto spuštění programu se ale dočkáme hlášení, že není možné spustit program dokud není definována cílová aplikace. To je ovšem v pořádku. V adresáři, ve kterém máme projekt uložen, se nám objeví nový soubor s názvem project1.dll.
A to je vše o co nám v dnešním díle šlo. Ještě na závěr jedno malé upozornění. Všichni ti z vás, kteří již používají winamp verzi 3 a výše si budou muset nainstalovat takovou verzi, která podporuje plug-in moduly a nebo si nainstalovat balíček který vám to umožní. Samozřejmě je volně ke stažení na stránkách www.winamp.com. Zdrojový kód programu k dnešnímu dílu si můžete stáhnout (zde 162kB). Příště se podíváme podrobně na některé další konstanty, které jsme dnes použili a také se naučíme jak získat data reprezentující reprodukovaný zvuk a ukážeme si jednoduché příklady kreslení zvukových spekter.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: