Archivos Python Scipy FFT wav

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?

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:
señal

Aquí está el espectro. espectro

Para obtener la salida correcta, tendrá que convertir el xlabel a la frecuencia para 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.

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()