Question

Le traitement audio est assez nouveau pour moi. Et en utilisant actuellement Python Numpy pour le traitement des fichiers wave. Après avoir calculé la matrice FFT Je reçois des valeurs de puissance bruyants pour les fréquences non existantes. Je suis intéressé par la visualisation des données et la précision est pas une priorité. Yat-il un moyen sûr de calculer la valeur de découpage pour supprimer ces valeurs, ou devrais-je utiliser toutes les matrices de FFT pour chaque ensemble d'échantillons à venir avec un nombre moyen?

concerne

Edit:

    from numpy import *
    import wave
    import pymedia.audio.sound as sound
    import time, struct
    from pylab import ion, plot, draw, show

    fp = wave.open("500-200f.wav", "rb")
    sample_rate = fp.getframerate()
    total_num_samps = fp.getnframes()
    fft_length = 2048.
    num_fft = (total_num_samps / fft_length ) - 2
    temp = zeros((num_fft,fft_length), float)

    for i in range(num_fft):
        tempb = fp.readframes(fft_length);
        data = struct.unpack("%dH"%(fft_length), tempb)
        temp[i,:] = array(data, short) 
    pts = fft_length/2+1
    data = (abs(fft.rfft(temp, fft_length)) / (pts))[:pts]

    x_axis = arange(pts)*sample_rate*.5/pts
    spec_range = pts
    plot(x_axis, data[0])
    show()

Voici le tracé en échelle non logarithmique, pour le fichier d'onde synthétique contenant 500Hz (fondu) + 200Hz onde sinusoïdale créée en utilisant Goldwave.

Était-ce utile?

La solution

formes d'onde Simulations ne doivent pas présenter comme TFR votre silhouette, donc quelque chose est très mal, et probablement pas avec la FFT, mais avec la forme d'onde d'entrée. Le principal problème dans votre parcelle ne sont pas les ondulations, mais les harmoniques autour de 1000 Hz, et la sous-harmonique à 500 Hz. Une forme d'onde simulée ne doit pas montrer tout cela (par exemple, voir mon tracé ci-dessous).

D'abord, vous voulez probablement juste essayer de tracer la forme d'onde brute, et pointera probablement un problème évident. En outre, il semble étrange d'avoir une onde à déballer short non signés, à savoir « H », et en particulier après ce pour ne pas avoir une forte composante de fréquence zéro.

Je suis en mesure d'obtenir une copie assez proche de votre FFT en appliquant écrêtage à la forme d'onde, comme cela a été suggéré à la fois par les harmoniques et sous-harmoniques supérieures (et Trevor). Vous pourriez être introduire d'écrêtement soit dans la simulation ou le déballage. De toute façon, je contournée en créant les formes d'onde en numpy pour commencer.

Voici ce que la bonne FFT devrait ressembler (à savoir essentiellement parfait, sauf pour l'élargissement des pics dus au fenêtrage)

Voici une forme d'onde d'une qui a été coupé (et est très similaire à votre FFT, de la sous-harmonique au motif précis des trois harmoniques supérieures autour de 1000 Hz)

Voici le code que j'utilisé pour générer ces

from numpy import *
from pylab import ion, plot, draw, show, xlabel, ylabel, figure

sample_rate = 20000.
times = arange(0, 10., 1./sample_rate)
wfm0 = sin(2*pi*200.*times)
wfm1 = sin(2*pi*500.*times) *(10.-times)/10.
wfm = wfm0+wfm1
#  int test
#wfm *= 2**8
#wfm = wfm.astype(int16)
#wfm = wfm.astype(float)
#  abs test
#wfm = abs(wfm)
#  clip test
#wfm = clip(wfm,  -1.2, 1.2)

fft_length = 5*2048.
total_num_samps = len(times)
num_fft = (total_num_samps / fft_length ) - 2
temp = zeros((num_fft,fft_length), float)

for i in range(num_fft):
    temp[i,:] = wfm[i*fft_length:(i+1)*fft_length] 
pts = fft_length/2+1
data = (abs(fft.rfft(temp, fft_length)) / (pts))[:pts]

x_axis = arange(pts)*sample_rate*.5/pts
spec_range = pts
plot(x_axis, data[2], linewidth=3)
xlabel("freq (Hz)")
ylabel('abs(FFT)')
show()

Autres conseils

FFT parce qu'ils sont fenêtré et échantillonné faire aliasing et d'échantillonnage dans le domaine des fréquences aussi bien. Filtrage dans le domaine temporel est la multiplication seulement dans le domaine de fréquence de sorte que vous pouvez appliquer juste un filtre qui est juste multiplie chaque fréquence par une valeur de la fonction du filtre que vous utilisez. Par exemple multiplier par 1 dans la bande passante et par zéro tous étaient d'autre. Les valeurs inattendues sont probablement causées par aliasing où des fréquences plus élevées sont rabattus à ceux que vous voyez. signal original doit être limité en bande à la moitié de votre taux d'échantillonnage ou vous obtiendrez aliasing . Plus inquiétant est aliasing qui dénature la zone d'intérêt, car pour cette bande de fréquences que vous voulez savoir que la fréquence est de celle attendue.

L'autre chose à garder à l'esprit est que lorsque vous prenez un morceau de données à partir d'un fichier wave que vous multiplierez mathmatically par une onde carrée. Cela provoque une sinx / x à convoluée avec la réponse en fréquence pour minimiser cela, vous pouvez multiplier le signal fenêtré original avec quelque chose comme un fenêtre Hanning .

Il convient de mentionner pour une FFT 1D que le premier élément (index [0]) contient le terme de courant continu (fréquence nulle), les éléments [1:N/2] contiennent les fréquences positives et les éléments [N/2+1:N-1] contiennent les fréquences négatives. Puisque vous n'avez pas fourni un exemple de code ou des informations supplémentaires sur la sortie de votre FFT, je ne peux pas exclure la possibilité que les « valeurs de puissance bruyants à des fréquences non existantes » ne sont pas seulement les fréquences négatives de votre spectre.


EDIT : est un exemple d'une FFT radix-2 mis en oeuvre dans le python pur avec une routine de test simple qui trouve la FFT d'une impulsion rectangulaire, [1.,1.,1.,1.,0.,0.,0.,0.]. Vous pouvez exécuter l'exemple sur CodePad et voir que la FFT de cette séquence est

[0j,                    Negative frequencies
(1+0.414213562373j),    ^
0j,                     |
(1+2.41421356237j),     |
(4+0j),                <= DC term
(1-2.41421356237j),     |
0j,                     v
(1-0.414213562373j)]    Positive frequencies

Notez que le code imprime les coefficients de Fourier dans l'ordre de fréquence croissante, à savoir à partir de la fréquence la plus élevée négative à courant continu, puis jusqu'à la plus haute fréquence positive.

Je ne sais pas assez de votre question pour répondre à quoi que ce soit spécifique.

Mais voici quelques choses à essayer de mes propres TFR écrit d'expérience:

  • Assurez-vous que vous suivez la règle Nyquist
  • Si vous regardez la sortie linéaire de la FFT ... vous aurez du mal à voir votre signal et pense que tout est cassé. Assurez-vous que vous êtes à la recherche à la dB de votre amplitude FFT. (À savoir "plot (10 * log10 (abs (fft (x))))")
  • Créer une fonction UnitTest pour votre FFT () par l'alimentation produit des données comme un son pur. Puis nourrir les mêmes données générées à la FFT de Matlab (). Faites une diff valeur absolue entre les deux séries de données de sortie et assurez-vous que la différence de valeur absolue max est quelque chose comme 10 ^ -6 (à savoir la seule différence est causée par de petites erreurs en virgule flottante)
  • Assurez-vous fenêtrage vos données

Si toutes ces trois choses fonctionnent, votre fft est très bien. Et vos données d'entrée est probablement la question.

Temps de coupure doamin apparaît comme des images miroir du signal dans le domaine de fréquence à intervalles réguliers spécifiques avec moins d'amplitude.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top