2017-03-12 1 views
1

Salut tout j'ai un son avec du bruit.Je veux supprimer ce bruit comment puis-je l'enlever?Comment supprimer le bruit dans un son avec allpassfilter dans matlab?

son origine: Zamfir-EinsamerHirte

Noisy son: Zamfir-EinsamerHirte_noisy

[y4,Fs]=audioread('Zamfir-EinsamerHirte_noisy.ogg'); 
ffty4=fft(y4); 

d'abord, j'analysé le signal

shiftedffty4=fftshift(ffty4); 
spectrumy41=abs(shiftedffty4); 
phaseffty41 = angle(shiftedffty4); 

N4=length(spectrumy41); 
t4=-Fs/2:Fs/N4:Fs/2-Fs/N4; 
spectrumy42=abs(fftshift(ffty4))/N4; 
phaseffty42=angle(fftshift(ffty4)); 

Deuxièmement, je fait un filtre passe-tout avec la même longueur de spectre et le produit avec fft de son bruyant et fait fft inverse et enlevé des parties imaginaires et joué le son. Le son reste avec le bruit

allpassfilter=ones([N4,2]); 
allpassfilter(spectrumy42>1e+06)=0; 
filteredy4=allpassfilter.*ffty4; 
filteredyeni4=ifft(filteredy4); 
filteredyy4=real(filteredyeni4); 
sound(filteredyy4,Fs); 

Mais je ne pouvais pas enlever bruit.Système problème est que je ne sais pas comment faire zéro, la valeur du bruit (endroit où le bruit a) dans allpassfilter comme ci-dessous:

allpassfilter(spectrumy42>1e+06)=0; 

Comment puis-je le faire? !!!Toute aide serait appréciée!!!! Merci d'avance.

Répondre

0

J'ai téléchargé les fichiers audio propres et bruyants. Analysons d'abord une petite partie de l'audio.

n=1024*8; % a small portion of data 
w1=1e5; 
w2=w1+n-1; 

sig_noisy=data_n(w1:w2,1); % noisy audio 
sig_clean=data_c(w1:w2,1); % clean audio 

figure; hold all 
plot(sig_noisy,'b') 
plot(sig_clean,'r','LineWidth',2) 
ylim([-1.5 1.5]) 
legend('Noisy','Clean') 

enter image description here

Comme on le voit ici, le son bruyant est en quelque sorte saturé et version tronquée du signal propre. Tronquer un signal provoque des harmoniques à des fréquences plus élevées. Regardons le spectre de puissance densités des signaux.

n=1024*1; % a smaller portion of data 
w1=1e5; 
w2=w1+n-1; 

sig_noisy=data_n(w1:w2,1); % noisy 
sig_clean=data_c(w1:w2,1); % clean 

[psd_noisy, f] = pwelch(sig_noisy); 
[psd_clean, ~] = pwelch(sig_clean); 

figure; hold all 
plot(f/pi,db(psd_noisy),'b') 
plot(f/pi,db(psd_clean),'r') 
xlabel('Normalized Freq.') 
legend('Noisy','Clean') 

enter image description here

Vous voyez que l'audio bruyant a des harmoniques plus le bruit à des fréquences élevées. Eh bien, maintenant, si vous supposez que les caractéristiques du bruit ne changent pas à la fin de l'audio, alors vous pouvez concevoir un filtre en regardant cette petite partie de l'audio. Puisque vous avez déjà un signal bruyant et propre ensemble, pourquoi ne pas utiliser la méthode de déconvolution.

Par exemple, si vous Deconvolve le signal propre avec une bruyante, puis vous obtenez la réponse inverse de votre système (h_inv), qui est aussi les coefficients de filtre que vous pouvez utiliser pour filtrer le signal bruyant

(sig_noisy = sig_clean * h).

Ici j'utilise la méthode de déconvolution de Wiener. Notez également que cette fonction n'est pas destinée à être utilisée uniquement pour les images, vous pouvez également utiliser les méthodes de déconvolution dans Matlab avec des signaux 1D.

h_inv=deconvwnr(sig_clean,sig_noisy); 

figure,plot(h_inv) 
legend('h^-^1') 

enter image description here

Comme je l'ai dit, ce sont les coefficients de filtre dont vous avez besoin.Par exemple, si je filtre le signal bruyant avec h_inv:

sig_filtered=conv(sig_noisy,h_inv,'same'); 
[psd_filtered, ~] = pwelch(sig_filtered); 

figure; hold all 
plot(f/pi,db(psd_noisy),'b') 
plot(f/pi,db(psd_clean),'r') 
plot(f/pi,db(psd_filtered),'k') 
xlabel('Normalized Freq.') 
legend('Noisy','Clean','Filtered') 

enter image description here

Le spectre de signal filtré est assez proche du spectre du signal propre. Maintenant que vous avez les coefficients de filtre, il suffit de filtrer tout l'audio bruyant avec h_inv et d'écouter le résultat.

filtered_all=conv(data_n(:,1),h_inv,'same'); 
sound(filtered_all,48000) 

Vous pouvez essayer d'autres méthodes de déconvolution et voir les résultats. Vous pouvez également mettre à zéro le spectre indésirable dans le domaine de Fourier et inverser le spectre pour un signal propre. Cependant, comme le signal est trop long, vous devrez le faire dans une fenêtre coulissante. Vous pouvez également concevoir des filtres coupe-bande en cascade pour filtrer chaque harmonique séparément.

Je vois qu'il y a quatre harmoniques stron. Concevez donc quatre filtres coupe-bande pour chacun et un filtre passe-bas pour filtrer le bruit haute fréquence.

% First notch 
fc1=0.0001; bw1=0.05; N=4; 
f = fdesign.notch('N,F0,BW',N,fc1,bw1); h = design(f); 

% Second notch 
fc2=0.21; bw2=0.2; 
f = fdesign.notch('N,F0,BW',N,fc2,bw2); h2 = design(f); 

% Third notch 
fc3=0.41; bw3=0.2; 
f = fdesign.notch('N,F0,BW',N,fc3,bw3); h3 = design(f); 

% Fourth notch 
fc4=0.58; bw4=0.2; 
f = fdesign.notch('N,F0,BW',N,fc4,bw4); h4 = design(f); 

% A Final lowpass filter 
f = fdesign.lowpass('Fp,Fst,Ap,Ast',0.6,0.65,1,30); h5 = design(f); 

% Cascade the filters 
hd = dfilt.cascade(h, h2, h3, h4, h5); 

% See the filter characterisctic 
ff=fvtool(hd,'Color','white'); 

% Now we can filter our 
sig_filtered2 = filter(hd,sig_noisy); 
[psd_filtered2,f] = pwelch(sig_filtered2); 

figure; hold all 
plot(f/pi,db(psd_noisy),'b'); 
plot(f/pi,db(psd_clean),'r'); 
plot(f/pi,db(psd_filtered2),'k'); 
xlabel('Normalized Freq.') 
legend('Noisy','Clean','Filtered') 

enter image description here

enter image description here

Vous pouvez maintenant filtrer l'ensemble audio

filtered_all2 = filter(hd,data_n(:,1)); 
sound(filtered_all2,48000) 

Hope I a aidé.

+0

merci. oui j'ai les deux, son propre et bruyant mais j'utiliserai un son clair pour vérifier, pas pour nettoyer le son bruyant.Et Notre proposition est de ne pas utiliser de filtre intérieur de matlab. nous devons faire un filtre passe-tout et faire la partie de bruit zéro puis produit de point avec le bruit bruyant pour enlever le bruit en freq. domaine. Donc, j'ai juste besoin de trouver l'emplacement du bruit, donc je vais faire le dernier code que j'ai demandé en question. Ceci est un devoir donc j'ai besoin de nettoyer de cette façon. –

+0

Ensuite, vous pouvez utiliser la deuxième approche que j'ai suggérée (filtres notch en cascade). Si vous voulez le faire avec FFT, vous pouvez le faire dans une petite partie des données, car le signal lui-même est trop long. – Ozcan