transformada - Archivos Python Scipy FFT wav
numpy fft python example (2)
Tengo un puñado de archivos wav. Me gustaría usar SciPy FFT para trazar el espectro de frecuencias de estos archivos wav. ¿Cómo voy a hacer esto?
Podrías usar el siguiente código para hacer la transformación:
#!/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()
Python
proporciona varias api para hacer esto bastante rápido. Descargo el archivo wav sheep-bleats desde este enlace . Puede guardarlo en el escritorio y guardarlo allí dentro de la terminal. Estas líneas en el indicador de python
deberían ser suficientes: (omitir >>>
)
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()
Aquí hay un gráfico para la señal de entrada:
Aquí está el espectro.
Para la salida correcta, tendrá que convertir el xlabel
a la frecuencia de la gráfica del espectro.
k = arange(len(data))
T = len(data)/fs # where fs is the sampling frequency
frqLabel = k/T
Si tiene que lidiar con un montón de archivos, puede implementar esto como una función: ponga estas líneas en el 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'')
Por test.wav
, tengo test.wav
y test2.wav
en el directorio de trabajo actual, el siguiente comando en la interfaz de solicitud de python
es suficiente: importar mapa test2 (test2.f, [''test.wav'', ''test2.wav''])
Suponiendo que tiene 100 archivos de este tipo y no desea escribir sus nombres individualmente, necesita el paquete glob
:
import glob
import test2
files = glob.glob(''./*.wav'')
for ele in files:
f(ele)
quit()
Deberá agregar getparams
en el test2.f si sus archivos .wav no son del mismo bit.