Python Scipy FFT WAV files

j'ai une poignée de fichiers wav. J'aimerais utiliser SciPy FFT pour tracer le spectre de fréquences de ces fichiers wav. Comment pourrais-je aller sur le faire?

24
demandé sur user1802143 2014-04-30 04:31:20

2 réponses

Python fournit plusieurs api pour faire cela assez rapidement. Je télécharge le fichier WAV sheep-bleats de ce lien. Vous pouvez l'enregistrer sur le bureau et cd là à l'intérieur du terminal. Ces lignes dans le python l'invite devrait suffire: (omit >>>)

import matplotlib.pyplot as plt
from scipy.fftpack import fft
from scipy.io import wavfile # get the api
fs, data = wavfile.read('test.wav') # load the data
a = data.T[0] # this is a two channel soundtrack, I get the first track
b=[(ele/2**8.)*2-1 for ele in a] # this is 8-bit track, b is now normalized on [-1,1)
c = fft(b) # calculate fourier transform (complex numbers list)
d = len(c)/2  # you only need half of the fft list (real signal symmetry)
plt.plot(abs(c[:(d-1)]),'r') 
plt.show()

voici un tracé pour le signal d'entrée:

signal

Voici le spectre spectrum

Pour la sortie correcte, vous aurez à convertir le xlabel à la fréquence du tracé spectral.

k = arange(len(data))
T = len(data)/fs  # where fs is the sampling frequency
frqLabel = k/T  

si vous avez affaire à un tas de fichiers, vous pouvez l'implémenter comme une fonction: mettre ces lignes dans le test2.py:

import matplotlib.pyplot as plt
from scipy.io import wavfile # get the api
from scipy.fftpack import fft
from pylab import *

def f(filename):
    fs, data = wavfile.read(filename) # load the data
    a = data.T[0] # this is a two channel soundtrack, I get the first track
    b=[(ele/2**8.)*2-1 for ele in a] # this is 8-bit track, b is now normalized on [-1,1)
    c = fft(b) # create a list of complex number
    d = len(c)/2  # you only need half of the fft list
    plt.plot(abs(c[:(d-1)]),'r')
    savefig(filename+'.png',bbox_inches='tight')

Dire, j'ai test.wav et test2.wav dans le dir de travail actuel, la commande suivante dans python l'interface rapide est suffisante: importation test2 carte(test2.F, ['test.WAV', ' test2.wav'])

en supposant que vous avez 100 fichiers de ce type et que vous n'en avez pas vous voulez taper leurs noms individuellement, vous avez besoin du glob paquet:

import glob
import test2
files = glob.glob('./*.wav')
for ele in files:
    f(ele)
quit()

vous devrez ajouter getparams dans le test2.f si votre .les fichiers wav ne sont pas du même bit.

50
répondu Shenghui 2015-12-01 20:06:33

Vous pouvez utiliser le code suivant pour faire le transformer:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
import scipy.io.wavfile as wavfile
import scipy
import scipy.fftpack
import numpy as np
from matplotlib import pyplot as plt

fs_rate, signal = wavfile.read("output.wav")
print ("Frequency sampling", fs_rate)
l_audio = len(signal.shape)
print ("Channels", l_audio)
if l_audio == 2:
    signal = signal.sum(axis=1) / 2
N = signal.shape[0]
print ("Complete Samplings N", N)
secs = N / float(fs_rate)
print ("secs", secs)
Ts = 1.0/fs_rate # sampling interval in time
print ("Timestep between samples Ts", Ts)
t = scipy.arange(0, secs, Ts) # time vector as scipy arange field / numpy.ndarray
FFT = abs(scipy.fft(signal))
FFT_side = FFT[range(N/2)] # one side FFT range
freqs = scipy.fftpack.fftfreq(signal.size, t[1]-t[0])
fft_freqs = np.array(freqs)
freqs_side = freqs[range(N/2)] # one side frequency range
fft_freqs_side = np.array(freqs_side)
plt.subplot(311)
p1 = plt.plot(t, signal, "g") # plotting the signal
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.subplot(312)
p2 = plt.plot(freqs, FFT, "r") # plotting the complete fft spectrum
plt.xlabel('Frequency (Hz)')
plt.ylabel('Count dbl-sided')
plt.subplot(313)
p3 = plt.plot(freqs_side, abs(FFT_side), "b") # plotting the positive fft spectrum
plt.xlabel('Frequency (Hz)')
plt.ylabel('Count single-sided')
plt.show()
1
répondu bunkus 2018-03-23 11:08:47