Hangkártyák programozása retro 23.

9. Mesterséges hangzás kialakítása a gyakorlatban

  1. A kialakítandó hangzásnak megfelelő terem, illetve hangtér kiválasztása. Ilyenkor ügyelni kell a hangforrás (egy vagy több hangszóró) és a mikrofon, illetve mikrofonok, vagy műfej elhelyezésére. Ugyanis a kialakítandó hangzás attól is függ nagymértékben, hogy hova képzeljük a hallgató személyt, illetve pl. a zenekart.
  2. A programok és hangminták telepítése a lemezmellékletről történik, alapesetben a Program Files\Spiller\Diplomamunka könyvtárba. Ezen belül az ASF könyvtárban található maga a mesterséges hangzást kialakító program, melynek az Artificial Sound Field (Mesterséges hangtér) fantázianevet adtam. A Program Files\Spiller\Diplomamunka\CppDLL alkönyvtárban az ASF program által használt Fourier transzformációs és konvolúciós függvényeket tartalmazó DLL C++ kódja található. A Program Files\Spiller\Diplomamunka\Test könyvtár tartalmazza mindazon programokat, amelyekkel a hangkártya programozása során foglalkoztunk, illetve itt található a legfontosabb program: Rec.exe, amely az impulzusválasz tesztet végrehajtja. A Program Files\Spiller\Diplomamunka\Samples könyvtárba történik a hangminták telepítése. Ezen belül négy alkönyvtár található: Others: egyéb vizsgálódásra alkalmas hangminták, Responses: különböző hangterek impulzusválaszai, Studio: stúdió minőségű, vagy rendkívül kicsi „teremhangot” tartalmazó felvételek, Results: a stúdiófelvételek és az impulzusválaszok konvolúciójaként létrehozott, az adott hangtérnek megfelelő hangzással rendelkező hangminta eredmények.
  3. Ha mindent megfelelően elrendeztünk, jöhet a teszt. Miután megtettük a programbeli szükséges beállításokat is, a dolgunk csupán annyi, hogy a DOS parancssorába begépeljük a felvevő program nevét és paraméterét, amely nem lesz más, mint a felvétel eredményének mentési útvonala. Például Rec C:\dokumnetumok\test.sam.
  4. Ellenőrzés képen vissza is játszhatjuk a felvétel eredményét, hasonló módon, mint ahogy a felvétel történt: Play C:\dokumnetumok\test.sam. A Scroll.pas nevű Pascal programmal meg is tekinthetjük a felvétel időfüggvényét. Ez azonban nem paraméteresen működik, így futtatásához szükségünk van valamilyen keretrendszerre.
  5. Ha minden rendben, akkor elindíthatjuk az ASF programot, s nekiláthatunk függvényeink elemzésének, illetve a mesterséges hangzás létrehozásának.
  6. Miután elmentettük a konvolúció eredményét, azt visszahallgathatjuk a 3. pontban bemutatott módon.

Az ASF program használatának ismertetése:

  1. A File menüpont Open Impulse Response parancsával nyithatjuk meg az impulzusválasz teszt eredmény-függvényét. A megjelenő párbeszédablakból kiválaszthatjuk a keresett hangmintát. Természetesen akármilyen hangmintát kiválaszthatunk vizsgálat céljából, de ha értelmes eredményt kívánunk elérni a konvolúcióval, célszerű itt az impulzusválaszt megnyitni. Megnyitást követően a függvény grafikusan is megjelenik az ablakban, amelynek időfüggvénye a gördítősáv segítségével vizsgálható.
  2. A függvényen önmagában is végezhetünk transzformációkat, de ügyeljünk arra, hogy a konvolúció előtt mindig eredeti állapotba állítsuk vissza. A Tools menüpont Fast Fourier Transform almenüjéből két pont választható: Normal és Inverse. Közvetlenül a hangminta megnyitását követően az Inverse lesz kipipálva, ami azt jelzi, nincs transzformált állapotban a függvényünk. Ha rákattintunk a Normal-ra, megkapjuk a függvény gyors Fourier transzformáltját, amely grafikusan is látható lesz, s amely az időfüggvényhez hasonlatosan görgetéssel vizsgálható. Természetesen kattintáskor a Normal kipipált állapotba kerül, jelezve, hogy a függvényünk transzformált állapotban van. Ha az Inverse pontra kattintunk, megtörténik a visszatranszformálás.
  3. A második függvényünk esetében is ugyanúgy kell eljárni, mint az első esetében, csupán annyi a különbség, hogy azt a File Open Sample menüpontjával nyithatjuk meg. A két beolvasott függvény, illetve a majdani eredmény között az ablak alsó részén elhelyezkedő gombok segítségével lehet váltani.
  4. Az Options Log of NFFT paranccsal adhatjuk meg, hogy hány alappontra kívánjuk elvégezni a transzformációt. Ha például 10-et választunk, akkor az alappontok száma: 1024, mivel a listából az alpontok számának kettesalapú logaritmusát kell kiválasztani.
  5. A legfontosabb parancs a Tools menü Convolution with the help of FFT pontja, amely magát a konvolúciót végzi. Elvégzése után három függvényt vizsgálhatunk. Természetesen az eredmény spektrumát is megnézhetjük, majd az eredeti állapotába visszaállítva elmenthetjük a File\Save Result As menüponttal.

Érdemes néhány vizsgálatot is elvégezni a telepített hangminták segítségével. A telepítést követően a Program Files\Spiller\Diplomamunka\Samples\Studio könyvtár hangmintái között található egy stúdió felvétel 2cd.sam néven, amely egy részlet a The Music of Ireland című CD válogatásról. Ezt a hangmintát fogjuk szoftveresen más és más hangzással ellátni.

Első lépésben nyissuk meg az impulzusválaszok közül a dist68.sam nevű hangmintát. Ez egy viszonylag kicsi, 2,2m x 3m x 2,2m-es, néhány bútordarabbal berendezett szobában készült. A hangforrás és a mikrofon egymással szemben helyezkedett el, 68 cm távolságra. Ha ezt konvolúciós viszonyba hozzuk a stúdió felvételünkkel és elmentjük annak eredményét, akkor hangmintát kapunk, amely úgy szól, mintha az eredeti felvételt a szobában a mikrofontól 68 cm távolságban vettük volna fel. Az eredmény függvény egyébként megtalálható a Program Files\Spiller\Diplomamunka\Samples\Results könyvtárban 2cd68.sam néven, amelyet összehasonlítva az eredetivel lényeges különbséget fogunk tapasztalni. További vizsgálatokat érdemes elvégezni a dist102.sam, dist136.sam és a dist200.sam impulzusválaszokkal, amelyek az említett szobában készültek különböző távolságokban.

Eddig csak olyan eseteket vizsgáltunk, amikor az első hanghullámok közvetlenül érték a mikrofont. Most hasonlítsuk össze a 2cd200.sam és a 2cd220.sam hangmintákat. Ugyanabban a szobában történt a felvétel különböző távolságban, azonban a második esetben a hangforrást és a mikrofont egymásnak ellenkező irányba fordítottuk, úgy hogy az utóbbi egy sarokban helyezkedett el. A két hangmintát meghallgatva meglepődötten tapasztalhatjuk, hogy a nagyobb távolságban végrehajtott teszt „erősebb” hangzást produkál. Erre a hangforrás és a mikrofon elhelyezése ad magyarázatot: a szoba sarka felerősítette a nem közvetlenül érkező hanghullámokat.

Miután megvizsgáltuk, hogy a távolság illetve a hangforrás és a mikrofon helyiségen belüli pozíciója miként befolyásolja a hangzást, nézzük meg, hogy különböző akusztikai terek milyen különbségeket okoznak összességében. Az eredmény függvényeink között található 2cdb2.sam, 2cdr2.sam és 2cdg.sam, amelyek közül az első egy fürdőszoba, a második egy nagyobb szoba és a harmadik egy garázs hangzását adja vissza A legmarkánsabb az összes közül talán a fürdőszoba, amely igen nagy utózengési idővel rendelkezik a rendkívül nagy csempe és tükörfelületnek köszönhetően.

Végül nézzük meg a mesterséges visszhang kialakításának lehetőségeit. Itt ahelyett, hogy egy valódi visszhangot produkáló hangteret kerestem volna, csaláshoz folyamodtam. Ugyanúgy jártam el az impulzusválasz tesztnél, mint bármilyen más terem esetében, csupán annyi volt a különbség, hogy több impulzust generáltam egymás után, attól függően, hogy milyen időkéséssel akartam létrehozni a visszhangot, illetve egyszeres, vagy többszörös visszhangot akartam-e. Ha például a tihanyi visszhangot szeretném modellezni, akkor egymás után két impulzust kell generálni, mivel egyszeres visszhangról van szó. Természetesen az első nem lehet olyan „magas”, mint a másik, mivel számolnunk kell bizonyos energiaveszteséggel. A hangnak kb. 1000 m-t kell megtennie, ami 340 m/s-os sebesség mellet 2,94 s-ot jelent, esetünkben hangmintára átszámítva: 129654. Azonban a rendszer is rendelkezik bizonyos időkéséssel, így 129654-nél kisseb kell, hogy legyen a két impulzus távolsága. Az eredményt visszahallgatva egyértelmű, hogy az nem tökéletes, mert rendkívüli módon zeng. Ennek az oka az, hogy nem szabadtérben hajtottuk végre az impulzusválasz tesztet, hanem egy teremben, így annak az utózengése megmaradt a hangmintán. Ez azonban jó példa lehet arra, hogy miként lehet különböző termek hangzásait „összekeverni”. A gyakorlatban is sokszor találkozunk olyan esettel, amikor van egy visszhangosított termünk, amelynek nem megfelelő az utózengése, ugyanakkor szeretnénk a termenek a visszhang tulajdonságát megőrizni. Ilyenkor nincs mit tennünk, mint a megfelelő utózengésű teremben mesterségesen létrehozni a visszhangot és az így keletkező válaszfüggvénnyel konvolúciós szűrést végezni a stúdió felvételen. A 3.4. pontban említett, nem kívánatos teremvisszhangok kiküszöbölése is lehetséges hasonló módszerrel.

Egyszeres visszhanggal rendelkező termet modellez 2cdecho2.sam. Szintén egyszeres visszhangra mutat példát vecho3.sam, a különbség annyi, hogy itt egy rövid mondat hangzik el. A vfecho.sam  a csörgővisszhangot igyekszik bemutatni, amely a többszörös visszhang egy speciális fajtája. Végül pedig a tihanyi visszhang időkésését utánzó hangállományt érdemes megvizsgálni: vtihany.sam.

Látható tehát, hogy ahelyett, hogy az adott akusztikai térben vettük volna fel a teljes hanganyagot elég volt csupán az impulzusválasz tesztet elvégezni, majd annak eredményét tárolni, ezáltal időt spórolva és lehetővé téve az újboli felhasználáhatóságot. Magyarán nem kell mindig az adott hangversenytermbe, vagy templomba rohanni, hogy a teljes zeneművet ott vegyük fel az adott hangzás elérése érdekében, ha ezt megtehetjük otthon, vagy a stúdióban egy számítógép segítségével.

Végül eljutottunk odáig, hogy magát a tesztet sem a valóságos helyen hajtottuk végre, hanem modelleztük annak valamilyen tulajdonságát.

Irodalomjegyzék

[1]  Tarnóczy Tamás: Hangnyomás, hangosság, zajosság, Akadémia Kiadó, Budapest, 1984

[2]  Tarnóczy Tamás: Teremakusztika I-II. kötet, Akadémia Kiadó, Budapest, 1986

[3]  Peter M. Ridge – David M. Golden – Ivan Luk – Scott E. Sindorf: Sound Blaster: The Official Book, Panem – McGraw-Hill, Berkeley, California, 1994

[4]  László József: Hangkártya programozása Pascal és Assembly nyelven, Computer Books, Budapest, 1999

[5]  Bajusz – Bors – Csibra – Horváth: A PC-k hangja, COM-WARE, Budapest, 1995

[6]  Székely Vladimír: Képkorrekció, hanganalízis, térszámítás PC-n (Gyors Fourier transzformációs módszerek), Computer Books, Budapest, 1994

[7]  Gyimesi László: Digitális jelfeldolgozás, SZIF-UNIVERSITAS Kft., 1999

[8]  Giczy Gergő: Hanghatár, CHIP magazin, XII. évf., 1. szám, 92-96. oldal

[9]  Köhler Zsolt: Hangoskodás, Computer Panoráma, XI. évf., 6. szám, 40-47. oldal

[10]        Szittya Ottó: Digitális és analóg technika, LSI Oktató Központ, Budapest 1999

[11]        Markó Imre: PC-k konfigurálása és installálása (A hardver), LSI Oktató Központ, Budapest 1999

Reklámok

Hangkártyák programozása retro 22.

8.3. A Fourier térben végezhető konvolúció C függvénye

A következő struktúra definiálása szükséges:

typedef struct { int n;         // A függvény elemek száma

int n0;        // Az első elem valódi indexe

double *fv;    // Mutató a függvény elemek tömbjére

int ndft;      // A dft alappontok száma, vagy 0

complex *dft;  // Mutató a dft értékekre, vagy NULL

} fvtype;

A függvény az fvtype struktúrákban a Fourier transzformáltat is tárolja, azt csak akkor számolja újból, ha szükség van rá.

extern “C” __declspec(dllexport)

int WINAPI convol_by_fft(fvtype *fvta,fvtype *fvtb,fvtype *fvtres)

// A bemenő függvényeket és az eredmény függvényt kapja paraméternek

{ long int i,na,nb,nres,ndft,logndft;

double s,*dbuff,*dp1,*dp2;

complex *cp1,*cp2,*cp3;

//Előkészítések

na=fvta->n;

nb=fvtb->n;

nres=na+nb-1; //Az eredmény vektor hossza

ndft=1; //A DFT hossza

logndft=0;

while(ndft<nres) { ndft<<=1; logndft+=1; }

refft_prepare(logndft); //Az FFT előkészítése

//Operandusok transzformálása

if(dft_fvtype(fvta,ndft)) goto alloc_err;

if(dft_fvtype(fvtb,ndft)) goto alloc_err;

//Konvolúció

free_fvtype(fvtres);

fvtres->dft=(complex*)farcalloc(ndft,sizeof(double));

if(fvtres->dft==NULL) goto alloc_err;

cp1=fvta->dft;

cp2=fvtb->dft;

cp3=fvtres->dft;

cp3->re=cp1->re*cp2->re;

cp3->im=cp1->im*cp2->im;

cp1++; cp2++; cp3++;

for(i=1;i<ndft/2;i++) cx_mul(cp1++,cp2++,cp3++);

fvtres->ndft=ndft;

//Visszatranszformálás

dbuff=(double*)farcalloc(ndft,sizeof(double));

if(dbuff==NULL) goto alloc_err;

dp1=(double *)fvtres->dft;

dp2=dbuff;

s=(double)ndft;

for(i=0;i<ndft;i++) *(dp2++)=*(dp1++)*s;

reifft(dbuff);

//Az eredmény elhelyezése az eredményvektorban

fvtres->fv=(double*)farcalloc(nres,sizeof(double));

if(fvtres->fv==NULL) goto alloc_err2;

dp1=dbuff;

dp2=fvtres->fv;

for(i=0;i<nres;i++) *(dp2++)=*(dp1++);

fvtres->n=nres;

fvtres->n0=fvta->n0+fvtb->n0; //Kezdőpont offset

//Kilépések, hibajelzések

farfree(dbuff);

refft_close();

return(0);

alloc_err2:

farfree(dbuff);

alloc_err:

refft_close();

return(1);

}

A fenti függvény szintén megtalálható a F.27-ben.

A Delphi-ben közvetlenül alkalmazott C függvények deklarálása, illetve rövid leírása:

function ReFftPrepare(log_n:longint):integer;

stdcall; external ‘prjconvoldll.dll’ name ‘refft_prepare’;

A fenti függvény feladata, hogy előkészítse a bemenő valós vektor transzformációjához szükséges munkaterületeket és az exponenciális függvény táblázatos kezelését. A transzformáció elvégzése előtt mindig ezt a függvényt kell meghívni, s itt kell megadni, hogy hány alappontú transzformációt szeretnénk végezni.

procedure ReFftClose;

stdcall; external ‘prjconvoldll.dll’ name ‘refft_close’;

A ReFfftClose függvény, illetve eljárás a ReFftPrepare által lefoglalt munkaterületek felszabadítását végzi, ha már nem kívánunk további transzformációkat végezni.

procedure ReFft(poi:pdouble);

stdcall; external ‘prjconvoldll.dll’ name ‘refft’;

Ez az eljárás végzi a valós bemenő vektor gyors Fourier transzformációt, miután megtörtént a munkaterületek előkészítése és az exponenciális függvény táblázatos megadása. Algoritmusát és az azt megvalósító program kódját részletesen tárgyaltuk az előző fejezetekben.

procedure ReiFft(poi:pdouble);

stdcall; external ‘prjconvoldll.dll’ name ‘reifft’;

A ReiFft eljárás végzi az inverz gyors Fourier transzformációt, amely szintén a szükség előkészítések után végezhető el eredményesen. Paraméterként a transzformálandó vektor kezdetére mutató pointert vár.

procedure InitFvtype(fvt:pfvtype);

stdcall; external ‘prjconvoldll.dll’ name ‘init_fvtype’;

A fenti eljárás a kezdeti, üres állapotnak megfelelően kitölti az fvt struktúrát, illetve rekordot. Deklarációt követően használata kötelező, de a tapasztalat azt mutatja, hogy a Delphi eleve az üres állapotnak megfelelően tölti ki a struktúrát, vagyis elvégzi helyettünk az inicializálást. Delphi-ben használata inkább ajánlatos, mint kötelező érvényű.

function FillFvtype(n:longint;n0:longint;data:pdouble;fvt:pfvtype):integer;stdcal;external ‘prjconvoldll.dll’ name ‘fill_fvtype’;

A megfelelő adatsor alapján a FillFvtype függvény kitölti az adott struktúrát, illetve rekordot.

function Convolution(fvta:pfvtype;fvtb:pfvtype;fvtres:pfvtype):integer;

stdcall; external ‘prjconvoldll.dll’ name ‘convol_by_fft’;

A tulajdonképpeni konvolúciót végző függvény, amelynek mindhárom paramétere egy fvtype típusú rekord. A rutin meghatározza a konvolúció eredményének hosszát és az FFT alappontjainak minimálisan szükséges hosszúságát, majd előállítja a két operandus transzformáltját. Kiszámítja az operandusok DFT-inek szorzatát, és ezt az eredmény DFT mezőjére helyezi. Végül elvégzi az eredmény visszatranszformálását.

A következő metódus magának, a konvolúciónak a teljes menetét mutatja be:

procedure TForm1.Convolution1Click(Sender: TObject);

var i:longint;

begin

//A kurzorunk jelzi, hogy dolgozunk

screen.cursor:=crHourglass;

try

//Függvények inicializálása

InitFvtype(@fv1);

InitFvtype(@fv2);

InitFvtype(@fv3);

//Az operandus függvények előkészítése, hiba esetén jelzés, majd kilépés

if(FillFvtype(high(p1^)+1,0,@p1^,@fv1))<>0 then

begin

ShowMessage(‘Allocation error while FillFvtype!’);

exit;

end;

if (FillFvtype(high(p2^)+1,0,@p2^,@fv2))<>0 then

begin

ShowMessage(‘Allocation error while FillFvtype!’);

exit;

end;

//Konvolúció elvégzése, hiba esetén jelzés, majd kilépés

if (Convolution(@fv1,@fv2,@fv3))<>0 then

begin

ShowMessage(‘Allocation error while Convolution!’);

exit;

end;

//A konvolúció eredményének kiolvasása

for i:=low(pres^) to high(pres^)-1 do

begin

pres^[i]:=fv3.fv^;

inc(fv3.fv);

end;

//Ha végeztünk üzenet, illetve a kurzor visszaállítása

ShowMessage(‘Convolution ready!’);

finally

screen.cursor:=crDefault;

end;

button:=3;

//Az eredmény függvény grafikus megjelenítése

DrawWaveRes(pres^);

end;

Egy, az FFT elvégzésére alkalmas metódust is bemutatok:

procedure TForm1.normal1Click(Sender: TObject);

begin

//Jelölések tájékoztatásul: most normal FFT-t végzünk

normal1.checked:=true;

inverse1.checked:=false;

screen.cursor:=crHourGlass;

try

//A transzformálandó függvény kiválasztása

case button of

1:

begin

// Munkaterület, exp.tábla előkészítése,

// transzformáció alappontjainak száma

if ReFftPrepare(lognfft)<> 0 then

begin

ShowMessage(‘Allocation error while FFT!’);

exit;

end;//if

//Gyors Fourier transzformáció elvégzése

Refft(@p1^);

//Lefoglalt munkaterületek felszabadítása

ReFftClose;

//A transzformált grafikus megjelenítése

DrawWaveSam(p1^);

end;//1

2:

begin

if ReFftPrepare(lognfft)<> 0 then

begin

ShowMessage(‘Allocation error while FFT!’);

exit;

end;//if

Refft(@p2^);

ReFftClose;

DrawWaveSam(p2^);

end;//2

3:

begin

if ReFftPrepare(lognfft+1)<> 0 then

begin

ShowMessage(‘Allocation error while FFT!’);

exit;

end;//if

Refft(@pres^);

ReFftClose;

DrawWaveRes(pres^);

end;//3

end;//case

finally

screen.cursor:=crDefault;

end;

end;

Lejjebb, F.24-ben példát láthatunk a konvolúció eredményére.

A konvolúciót, illetve az FFT-t végző teljes Delphi forrás pedig a F.28-ban tanulmányozható.

F.24.a

Impulzusválasz függvénye

F.24.b

Tetszőleges gerjesztés függvénye

F.24.c

Konvolúció eredménye

F.24. Mesterséges hangzás megvalósítása konvolúcióval

Hangkártyák programozása retro 20.

8. Konvolúció a Fourier térben

Miután megismerkedtünk a diszkrét Fourier transzformációval és az azt megvalósító FFT-vel, a mesterséges hangzás létrehozásának elvét tárgyaljuk. Ahogy előzőleg említettem, erre a konvolúciót fogjuk használni. Nézzük meg először az elvét, illetve algoritmusát alapján és a megvalósítást végző program kódját [6] alapján.

8.1. Folytonos függvények konvolúciója

A konvolúció fogalmát egy egyszerű elektromos hálózat példáján keresztül fogjuk levezetni. Legyen adott egy áramkör, amely ellenállásokból és kondenzátorokból áll. A kondenzátorok miatt a hálózat bementére adott jel késéssel és némileg torzult formában jut el a kimenetre. Vezessünk be egy egyezményes mérőjelet, amelyet a hálózat bementére juttatunk és mérjük kimenetét, vagyis a bemenetre adott válaszát. E mérőjel legyen egy elég keskeny Dt szélességű feszültség impulzus. Az impulzus integrálja legyen egységnyi. Következésképp 1/Dt magas lesz. A Dt szélességű mérőimpulzusra adott rDt(t) válasz független Dt tényleges értékétől. Ez annál inkább tapasztalható, minél kisebb a Dt idő a válasz-impulzus lefutásának teljes tartamához képest. Ebből következik, hogy a Dt időt a hálózat tulajdonságait figyelembe véve kell megválasztani, mindig úgy, hogy Dt igen kicsi legyen a hálózat tranziens időihez képest. (Lásd F.21.)

F.21. Elektromos hálózat impulzusválasza

Természetesen a mérőjelet függetlenné tehetjük az adott hálózattól, mégpedig a Dirac-d gerjesztés bevezetésével. Ez esetben Dt kicsi bármely hálózat tranziens időihez képest, tehát Dt->0, vagyis mérőjelünk végtelenül keskeny, de ugyanakkor egységnyi területű impulzus, tehát végtelen magas is egyben. A hálózatnak a Dirac-d bemenetre adott válasz-függvénye a hálózat súlyfüggvénye. Ha tehát Dt tart zérushoz, a Dt szélességű impulzusra adott válasz tart a súlyfüggvényhez:

(8.1)

Dirac-d tulajdonságai a követezőek:

  • Értéke minden t értéknél zérus, kivéve a t=0 pillanatot, amikor végtelen,
  • Integrálja egységnyi.

Látható, hogy válasz csak a gerjesztés követően jön létre, vagyis míg a bemeneti Dirac-d a t=0 pillanatban jelentkezik, addig a súlyfüggvény csak a t>=0 pillanatokban lehet zérustól eltérő.

Ahhoz, hogy megértsük a hálózat tetszőleges gerjesztésére adott válasz számolását, tekintsük a következő példát. A bemenő függvényünket bontsuk fel Dt szélességű szakaszokra és közelítsük a függvényt a szakasz elején felvett értékével. Eredményként a gerjesztő függvényt, mint impulzus sorozatot kapjuk meg. Egyetlen Dt szélességű impulzusra ismerjük a hálózat válaszát: rDt(t). Jelen esetben pedig több, különböző magasságú, különböző időpontban jelentkező bemenő impulzusunk van. (Lásd F.22.)

F.22. Tetszőleges gerjesztő függvény felbontása Dt szélességű impulzusokra

Az i-edik impulzus a t=0 időponthoz képest iDt-vel később jelentkezik és magassága nem 1/Dt, hanem g(iDt). Tehát a válasz több rDt(t) formájú függvény összege lesz, amelyek a gerjesztő impulzus időbeni eltolásának és változó magasságának megfelelően eltolva és konstanssal szorozva jelentkeznek:

(8.2)

Ne felejtsük el, hogy lineáris hálózatról van szó, így több gerjesztés együttes hatása egyenlő  az egyenkénti gerjesztések hatásának összegével.

Finomítsuk most végtelenül a gerjesztő függvény impulzusokra bontását, azaz Dt tartson zérushoz. Ekkor (8.2) summája alatt az rDt(t) válaszfüggvény az s(t) súlyfüggvényhez tart. Maga a summa egy integrál közelítő összege, ami Dt->0 határátmenettel a t=iDt szerinti integrálba megy át a következő módon:

(8.3)

A fenti képlet a hálózatelméletből ismeretes, lineáris rendszerekre vonatkozó Duhamel tétel alapján vezethető le. A képlet maga pedig az úgynevezett konvolúciós integrál.

Az integrálási határok abból adódnak, hogy az integrálásnak csak azon t tartományra kell kiterjednie, amelyen az integrandus nullától eltérő lehet. Mivel feltételezzük, hogy

s(t)=0 ha t<0,

g(t)=0 ha t<0                            (8.4)

a t<0 esetben g(t) biztosan zérus, a t>t esetben s(t-t) biztosan zérus.

A v(t) válaszfüggvény tehát a g(t) gerjesztési- és az s(t) súlyfüggvény konvolúciója szerint számolható:

v(t)=g(t) X s(t)                            (8.5)

A gyakorlatban a konvolúciós integrál értelmezése igen érdekes: a g(t) függvényre rárajzoljuk az s(t)-t, a negatív t értékek felé áttükrözve és az origóját t pontba eltolva. Majd a közös szakaszon szorzatukat integráljuk, vagyis nem teszünk mást, mint vesszük g(t) függvénynek az s(t) súlyfüggvénnyel súlyozott integrálját. A v(t) függvény t paraméterét változtatva az s(t) függvény kezdőpontja eltolódik, s az s(t) szinte végigcsúszik a g(t)-n, miközben mindig más szakaszon képződik a súlyozott átlag.

Meg kell említeni, hogy a konvolúciós szűrés átalában információveszteséggel jár. Ennek vizsgálatához ismét egy egyszerű elektromos hálózatot választunk. (Lásd F.23.)

F.23. Integráló tag és súlyfüggvénye

Az integráló tag súlyfüggvénye a következőképpen alakul:

s(t)=(1/t)e-t/t  ha t<=0

s(t)=0 ha t<0                            (8.6)

Az ezzel való konvolúció durván t nagyságú időtartományra való átlagolásnak felel meg. Ha t igen nagy a vizsgált jel tartamához képest, akkor ez a konvolúció közelítőleg a jel integrálját adja. Az átlagolás miatt a magasabb frekvencia összetevők egyre kisebb amplitúdóval jutnak át a rendszeren. Ha a szűrés hatását semlegesíteni szeretnénk, megpróbálhatjuk alkalmazni a konvolúció inverz műveletét, a dekonvolúciót, azonban számolnunk kell azzal, hogy a kimeneten véletlenszerű feszültségingadozás, vagyis zaj jelenik meg. Ha a jel magas frekvenciájú összetevői annyira legyengülnek, hogy a zajszint alá esnek, akkor a kiegyenlítő visszaerősítés már nem az eredeti komponenseket, hanem hozza vissza, hanem a zajt.