2010-09-30 25 views
1

J'ai un spectre d'amplitude FFT et je veux créer un filtre qui passe sélectivement des sources de bruit périodiques (par exemple des ondes sinusoïdales) et zéro sur les intervalles de fréquence associés au bruit de fond aléatoire. Je comprends que les transitions pointues dans le domaine freq créeront des artefacts de sonnerie une fois que ce filtre sera de retour dans le domaine temporel ... et donc je me demande s'il y a des règles de base pour lisser les transitions dans un tel filtre sonnerie. Par exemple, si la FFT a des intervalles de fréquence de 1M, et qu'il y a cinq spurs hors du fond de bruit de fond, je voudrais mettre à zéro tous les bins sauf le pic de crête associé à chacun des cinq spurs. La question est de savoir comment gérer les corbeilles de spur voisins pour éviter les artefacts dans le domaine temporel. Par exemple, la poubelle de chaque côté d'une corbeille doit-elle être réglée sur une amplitude de 50%? Devrait-on utiliser deux bacs de chaque côté d'un bac à éperons (le plus proche à 50% et le plus proche à 25%, etc.)? Toutes les pensées ont grandement apprécié. Merci!des règles de base pour lisser le spectre FFT pour éviter les artefacts lors de l'ajustement à la main?

Répondre

2

J'aime la méthode suivante:

  • Créer le spectre d'amplitude idéale (ne pas oublier de le rendre symétrique par rapport à DC)
  • transformée inverse au domaine temporel
  • Faites pivoter le bloc de la moitié du blocksize
  • Appliquer une fenêtre de Hann

Je trouve crée domaine de fréquence raisonnablement lisse résultat s, bien que je ne l'ai jamais essayé sur quelque chose d'aussi précis que ce que vous suggérez. Vous pouvez probablement faire un filtre plus net en utilisant une fenêtre de Kaiser-Bessel, mais vous devez choisir les paramètres de manière appropriée. Plus pointu, je suppose que peut-être vous pouvez réduire les lobes secondaires de 6 dB ou plus.

Voici un exemple de code Matlab/Octave. Pour tester les résultats, j'ai utilisé freqz(h, 1, length(h)*10);.

function [ht, htrot, htwin] = ArbBandPass(N, freqs) 
%# N = desired filter length 
%# freqs = array of frequencies, normalized by pi, to turn into passbands 
%# returns raw, rotated, and rotated+windowed coeffs in time domain 

if any(freqs >= 1) || any(freqs <= 0) 
    error('0 < passband frequency < 1.0 required to fit within (DC,pi)') 
end 

hf = zeros(N,1); %# magnitude spectrum from DC to 2*pi is intialized to 0 
%# In Matlabs FFT, idx 1 -> DC, idx 2 -> bin 1, idx N/2 -> Fs/2 - 1, idx N/2 + 1 -> Fs/2, idx N -> bin -1 
idxs = round(freqs * N/2)+1; %# indeces of passband freqs between DC and pi 
hf(idxs) = 1; %# set desired positive frequencies to 1 
hf(N - (idxs-2)) = 1; %# make sure 2-sided spectrum is symmetric, guarantees real filter coeffs in time domain 
ht = ifft(hf); %# this will have a small imaginary part due to numerical error 
if any(abs(imag(ht)) > 2*eps(max(abs(real(ht))))) 
    warning('Imaginary part of time domain signal surprisingly large - is the spectrum symmetric?') 
end 
ht = real(ht); %# discard tiny imag part from numerical error 
htrot = [ht((N/2 + 1):end) ; ht(1:(N/2))]; %# circularly rotate time domain block by N/2 points 
win = hann(N, 'periodic'); %# might want to use a window with a flatter mainlobe 
htwin = htrot .* win; 
htwin = htwin .* (N/sum(win)); %# normalize peak amplitude by compensating for width of window lineshape 
+0

Merci beaucoup mtrw. Je pensais à modifier les coefficients FFT sur les cases voisines, mais il semble que vous utilisiez la fenêtre de Hann pour obtenir quelque chose de similaire (les artefacts apparaîtront dans le domaine temporel, et la fenêtre de Hann l'améliorera en quelque sorte) . Dans mon cas, le «spectre d'amplitude idéal» serait une représentation binaire, où (en continuant l'exemple ci-dessus), j'en aurais cinq et les autres zéros - c'est ce que vous recommandez ici aussi? En outre, je ne suis pas sûr de ce que vous entendez par "faire pivoter le bloc de la moitié de la taille des blocs". Qu'est-ce qu'un bloc? Pouvez-vous donner un exemple? – ggkmath

+0

Aussi, quel est l'avantage de centrer le spectre sur DC? – ggkmath

+0

Réponses rapides: 1. oui, je suggère que la fenêtre s'occupe des bacs voisins. 2. Tourner les moyens de bloc inverser la première et la seconde moitié du filtre de domaine temporel après la FFT inverse. Blocksize est le nombre de points dans le filtre. 3. Vous devez vous assurer que la FFT inverse fournit des coefficients du domaine temps réel. Le spectre doit être hermitien symétrique (les seconds N/2 points sont des conjugués complexes du premier N/2). Vérifiez votre documentation FFT pour voir comment ils attendent de vous pour organiser les points. Je vais créer un exemple quand j'ai plus de temps ... – mtrw