Implementarea Aplicatiei Wiener Filtering Simulator

CAPITOLUL 5

IMPLEMENTAREA APLICAȚIEI WIENER FILTERING SIMULATOR

5.1 Funcția de filtrare WienerScalart96

Funcția de filtrare WienerScalart96 a fost preluată de pe site-ul web a companiei Mathworks, adresa web exactă este http://www.mathworks.com/matlabcentral/fileexchange/7673. Codul Funcției este listat in Anexa 1, iar funcționalitatea acesteia este prezentată în cele ce urmează.

Funcția de filtrare Wiener-Scalart a fost implementată în limbajul Matlab și are ca parametri de intrare semnalul audio care trebuie filtrat, frecvența de eșantionare a acestuia și lungimea liniștii inițiale. Se consideră ca orice semnal audio are la început niște eșantioane de liniște, în care este prezent doar zgomotul, pe baza căruia se extrage spectrul zgomotului care va fi folosit la filtrare. Filtrarea efectivă a semnalului se face pe baza metodei Overlap-Add.

Semnalul audio este parcurs cadru cu cadru utilizând o fereastră Hamming. Lungimea unui cadru, anume a ferestrei de analiză, este de 25 ms, din care, prin înmulțire cu frecvența de eșantionare se obține lungimea cadrului în număr de eșantioane. Nu s-a dat lungimea cadrului de parcurgere în număr de eșantioane deoarece frecvența de eșantionare variază de la un semnal audio la altul.

Funcția realizează în primul rând o filtrare de preaccentuare a semnalului audio. După aceasta, semnalul este împărțit în cadre care se suprapun (overlapping frames). Funcția care împarte semnalul audio în cadre (windowed segments) Funcționează în felul următor: se construiește o matrice pe a cărei coloane sunt cadrele obținute din semnalul audio inițial. Împartirea în cadre se face funcție de numărul de eșantioane pe fereastra de parcurgere, de procentul de shiftare (shift percentage) și tipul ferestrei de parcurgere, care în cazul de față va fi Hamming.

În urma acestei operații se face transformata Fourier a fiecărui cadru în parte și se calculează spectrul de putere, respectiv spectrul de fază ale acestora. Din durata de liniște inițială se calculează media spectrului de putere a zgomotului și varianta acestuia. Pe baza acestor valori urmează să se facă filtrarea efectivă. Se pornește de la o valoare predefinită a factorului de netezire și a celui de amplificare.

Cum a mai fost precizat, parcurgerea semnalului audio de filtrat se face cadru cu cadru. Pe fiecare cadru în parte se efectuează următoarele operații:

Se testează dacă în cadrul respectiv există vorbire (voice activity). Detectorul de vorbire – voice activity detector – Funcționează pe principiul distanței spectrale dintre spectrul cadrului curent și spectrul de zgomot calculat din perioada de liniște inițială (magnitude spectral distance). Parametri de intrare ai detectorului de vorbire sunt cadrul de semnal care urmează a fi analizat, spectrul de amplitudine al zgomotului, numărul de cadre de zgomot anterioare cadrului curent de la ultima detecție de activitate vocală și o margine de zgomot. Pe baza acestor parametri Funcția decide dacă cadrul curent conține vorbire sau doar zgomot și se incrementează sau resetează numărul de cadre de zgomot anterioare.

În cazul în care nu a fost detectată vorbire factorii de netezire și de amplificare sunt modificați.

Se efectuează netezirea și amplificarea spectrului cadrului de semnal audio.

În urma obținerii noilor cadre de semnal vocal se aplică metoda Overlap-Add pentru a obține semnalul audio filtrat. Trebuie precizat că operațiile pe cadre sunt efectuate în domeniul frecvența, deci reconstituirea semnalului va fi făcută tot în domeniul frecvență. Funcția OverlapAdd va avea ca parametri de intrare spectrul de amplitudine și fază a fiecărui cadru din semnalul inițial netezit, lungimea ferestrei de parcurgere și procentul de shiftare. După ce s-a obținut spectrul semnalului reconstituit se aplică transformata Fourier inversă pentru a obține semnalul în domeniul timp.

În final, semnalului i se va aplică unui filtru de dez-accentuare pentru a neutraliza efectul pre-accentuării și a obține varianta filtrată a semnalului audio inițial.

5.2 Implementarea aplicației

Semnalul vocal utilizat este reprezentat printr-o structură numită „wave”, care conține următoarele câmpuri: lungimea ferestrei de analiză, adică a cadrului („lc”), numărul de cadre („N”), numărul de eșantioane, precum și numărul total de cadre ale semnalului sonor („Nc”).

wave.file = sound;

wave.lc = 256; % lungimea ferestrei de analiză/lungimea unui cadru

wave.N = length(wave.file); % nr de eșantioane ale semnalului sonor

wave.Nc = floor(wave.N/wave.lc); % nr de cadre

În editorul de interfață grafică a utilitarului Matlab a fost implementată o aplicație, Wiener Filter Simulator, care realizează filtrarea semnalelor audio mono. În continuare este prezentată fereastra principală a aplicației:

Figura 5.1 Interfața aplicației de filtrare Wiener

Aplicația pune la dispoziția utilizatorului un meniu de unde se poate alege:

deschiderea unui fișier audio,

salvarea semnalului audio filtrat

închiderea aplicației.

Fiecare comandă poate fi accesată fie prin intermediul meniului, fie prin utilizarea unui Short-Cut de tipul Ctrl+litera. În figura 5 este prezentat meniul File, respectiv fereastra de deschidere a unui fișier audio.

Figura 5.2 Fereastra principală a aplicației, Meniul File și deschiderea unui fișier audio

În fereastra principală, în regiunea central-dreapta, aplicația pune la dispoziție două ferestre de afișare a semnalului. În prima fereastră este afișat semnalul afectat de zgomot iar în a doua este afișat semnalul obținut în urma operației de filtrare.

În partea stângă a ferestrei aplicației sunt puse la dispoziție un set de comenzi care presupun:

Adăugarea de zgomot la semnalul audio încărcat;

Selectarea modului de afișare a semnalului;

Filtrarea semnalului zgomotos.

Adăugarea zgomotului aditiv presupune adunarea unei secvențe aleatoare peste eșantioanele semnalului vocal inițial. Zgomotul poate fi simulat, sau poate fi real. În cazul zgomotului simulat, acesta este obținut cu ajutorul Funcțiilor Matlab randn() și rand(), și poate fi de distribuție Gaussiana, respectiv de distribuție uniformă. În cazul zgomotului real, acesta reprezintă semnale sonore înregistrate în mediul înconjurător: zgomotul întâlnit în autobuz, zgomotul de pe stradă sau zgomotul din trafic.

Ținând cont de faptul că zgomotul real provine din înregistrări efective, lungimea semnalului de zgomot nu va corespunde cu lungimea semnalului vocal inițial. Astfel, s-a făcut o comparare între cele două lungimi și au rezultat două cazuri:

Lungimea semnalului de zgomot e mai mare decât lungimea semnalului audio. În acest caz, zgomotul a fost scurtat la lungimea semnalului audio.

Lungimea semnalului audio e mai mare decât lungimea zgomotului. În acest caz zgomotul a fost adăugat într-un ciclu repetitiv pentru a acoperi toate eșantioanele semnalului audio.

Amplitudinea zgomotului este selectată prin intermediul unui slidebar ca un anume procent din amplitudinea maximă a semnalului inițial. În continuare este prezentată Funcția Matlab care realizează această sarcină:

Funcțion noiseAdd_Callback(hObject, eventdata, handles)

% hObject handle to noiseAdd (see GCBO)

% eventdata reserved – to be defined in a future version of MATLAB

% handles structure with handles and user data (see GUIDATA)

wave=handles.wave;

a=get(handles.noiseAmp,'Value');

if get(handles.simulatedNoise,'Value')==1

simNoiseType=get(handles.noiseType,'Value');

if simNoiseType==1

wave1=wave+max(wave)*randn(size(wave),1)*a;

set(handles.noisetype,'String',['Simulated gaussian noise of amplitude ' num2str(a*100) ' %']);

elseif simNoiseType==2

wave1=wave+max(wave)*rand(size(wave),1)*a;

set(handles.noisetype,'String',['Simulated uniform noise of amplitude ' num2str(a*100) ' %']);

end;

elseif get(handles.realNoise,'Value')==1

realNoiseType=get(handles.noiseSource,'Value');

%wave=wave/2;

if realNoiseType==1

noisesgn=wavread('Bus.wav');

%noisesgn=noisesgn/2;

if (length(wave)<=length(noisesgn))

wave1=wave+noisesgn(1:length(wave),1)*max(wave)*a;

else

for i=1:floor(length(wave)/length(noisesgn))

wave1((i-1)*length(noisesgn)+1:i*length(noisesgn))=wave((i-1)*length(noisesgn)+1:i*length(noisesgn))+noisesgn(:,1)*max(wave)*a;

end; wave1(floor(length(wave)/length(noisesgn))*length(noisesgn)+1:length(wave))=wave(floor(length(wave)/length(noisesgn))*length(noisesgn)+1:length(wave))+noisesgn(1:length(wave)-floor(length(wave)/length(noisesgn))*length(noisesgn),1)*max(wave)*a;

end;

set(handles.noisetype,'String',['Real noise from Bus of amplitude ' num2str(a*100) ' %']);

elseif realNoiseType==2

noisesgn=wavread('Street.wav');

if (length(wave)<=length(noisesgn))

wave1=wave+noisesgn(1:length(wave),1)*max(wave)*a;

else

for i=1:floor(length(wave)/length(noisesgn))

wave1((i-1)*length(noisesgn)+1:i*length(noisesgn))=wave((i-1)*length(noisesgn)+1:i*length(noisesgn))+noisesgn(:,1)*max(wave)*a;

end; wave1(floor(length(wave)/length(noisesgn))*length(noisesgn)+1:length(wave))=wave(floor(length(wave)/length(noisesgn))*length(noisesgn)+1:length(wave))+noisesgn(1:length(wave)-floor(length(wave)/length(noisesgn))*length(noisesgn),1)*max(wave)*a;

end;

set(handles.noisetype,'String',['Real noise from Street of amplitude ' num2str(a*100) ' %']);

elseif realNoiseType==3

noisesgn=wavread('Traffic.wav');

if (length(wave)<=length(noisesgn))

wave1=wave+noisesgn(1:length(wave),1)*max(wave)*a;

else

for i=1:floor(length(wave)/length(noisesgn))

wave1((i-1)*length(noisesgn)+1:i*length(noisesgn))=wave((i-1)*length(noisesgn)+1:i*length(noisesgn))+noisesgn(:,1)*max(wave)*a;

end;

wave1(floor(length(wave)/length(noisesgn))*length(noisesgn)+1:length(wave))=wave(floor(length(wave)/length(noisesgn))*length(noisesgn)+1:length(wave))+noisesgn(1:length(wave)-floor(length(wave)/length(noisesgn))*length(noisesgn),1)*max(wave)*a;

end;

set(handles.noisetype,'String',['Real noise from Traffic of amplitude ' num2str(a*100) ' %']);

end;

else wave1=wave;

set(handles.noisetype,'String','No added noise');

end;

Aplicația permite două moduri de afișare a semnalului: în domeniul timp și în domeniul frecventa. Afișarea în domeniul timp presupune afișarea cronogramei semnalului sonor. Pe axa absciselor este afișat timpul în secunde, acesta fiind obținut din numărul eșantionului împărțit la frecvența de eșantionare. Afișarea în domeniul frecvență presupune afișarea spectrogramei semnalului.

Funcția Matlab care realizează afișarea semnalului este prezentată în continuare:

Funcțion afiseaza(grafic,Fs,semnal,handles)

T=1/Fs;

t=(0:length(semnal)-1)*T;

if get(handles.timePlot,'Value')==1

subplot(grafic);

plot(t,semnal);

xlabel('Time (seconds)');

ylabel('Amplitude');

else

subplot(grafic);

specgram(semnal);

end;

Filtrarea semnalului vocal afectat de zgomot se face prin apelarea Funcției de filtrare Wiener-Scalart. Alegerea lungimii perioadei de liniște inițială se face prin intermediul unui slidebar disponibil sub fereastra în care este afișat semnalul zgomotos. În cazul în care lungimea perioadei de liniște inițială nu este selectată, aceasta este considerată implicit de 25 ms.

În continuare, în fereastra principală a aplicației este pusă la dispoziție o regiune în care sunt notate unele rezultate estimative. În primul rând este trecut tipul de zgomot ales și amplitudinea acestuia. Pe urmă este trecut raportul semnal zgomot (SNR) estimat al semnalului audio inițial, respectiv al semnalului obținut în urma filtrării. Este vorba de un raport semnal-zgomot estimat deoarece este obținut prin logaritmarea raportului dintre media puterii semnalului și media puterii zgomotului. Puterea medie a semnalului este calculată pe întreaga durată a semnalului sonor, iar puterea medie a zgomotului este calculată pe perioada de liniște inițială. Trebuie precizat ca raportul semnal-zgomot este unul estimativ. Întru-cât semnalul vocal este afectat într-o oarecare măsură de zgomot, puterea medie calculată nu corespunde puterii reale a semnalului fără zgomot, deci valoarea estimată a SNR nu va fi cea reală. Va fi însă sugestivă în vederea extragerii unor concluzii referitoare la performanțele Funcției de filtrare. SNR va fi estimat cu următoarea funcție Matlab:

Funcțion SNR = calculSNR(wave)

N=length(wave);

noise=wave(1:512);

% SNR

wave_sq = wave.*wave;

P_wave = sum(wave_sq)/N;

noise_sq = noise.*noise;

P_noise = sum(noise_sq)/512;

SNR = 10*log10(P_wave/P_noise);

În plus, pentru o comparație subiectivă, aplicația mai pune la dispoziție și câte un buton pentru ascultarea semnalului sonor inițial, respectiv a semnalului sonor filtrat.

Similar Posts