Python Scipy FFT wav 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23377665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Scipy FFT wav files
提问by user1802143
I have a handful of wav files. I'd like to use SciPy FFT to plot the frequency spectrum of these wav files. How would I go about doing this?
我有一些 wav 文件。我想使用 SciPy FFT 来绘制这些 wav 文件的频谱。我该怎么做呢?
回答by yshk
Python
provides several api to do this fairly quickly. I download the sheep-bleats wav file from this link. You can save it on the desktop and cd
there within terminal. These lines in the python
prompt should be enough: (omit >>>
)
Python
提供了几个 api 来相当快地做到这一点。我从这个链接下载了羊叫声 wav 文件。您可以将其保存在桌面和cd
终端内。python
提示中的这些行应该足够了:(省略>>>
)
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()
Here is a plot for the input signal:
这是输入信号的图:
Here is the spectrum
这是频谱
For the correct output, you will have to convert the xlabel
to the frequency for the spectrum plot.
为了获得正确的输出,您必须将 转换xlabel
为频谱图的频率。
k = arange(len(data))
T = len(data)/fs # where fs is the sampling frequency
frqLabel = k/T
If you are have to deal with a bunch of files, you can implement this as a function:
put these lines in the test2.py
:
如果您必须处理一堆文件,您可以将其实现为一个函数:将这些行放在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')
Say, I have test.wav
and test2.wav
in the current working dir, the following command in python
prompt interface is sufficient:
import test2
map(test2.f, ['test.wav','test2.wav'])
说,我有test.wav
并且test2.wav
在当前的工作目录中,python
提示界面中的以下命令就足够了: import test2 map(test2.f, ['test.wav','test2.wav'])
Assuming you have 100 such files and you do not want to type their names individually, you need the glob
package:
假设您有 100 个这样的文件并且您不想单独键入它们的名称,则需要以下glob
包:
import glob
import test2
files = glob.glob('./*.wav')
for ele in files:
f(ele)
quit()
You will need to add getparams
in the test2.f if your .wav files are not of the same bit.
getparams
如果您的 .wav 文件不是同一位,您将需要添加test2.f。
回答by bunkus
You could use the following code to do the transform:
您可以使用以下代码进行转换:
#!/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()