小學期的《信號與系統》課,要求寫一個頻率計數器,下面是我我的理解的頻率計數python
傅里葉變換的代碼:windows
# coding=utf-8 import numpy as np from scipy.io import wavfile import matplotlib.mlab as mlab import matplotlib.pyplot as plt class FrequencyCounter(): def loaddata(self, filename): try: samplerate, channels = wavfile.read(filename) self.data = np.mean(channels, axis=1) except: raise ValueError, 'Data Error' def fft(self, windowsize=4096, samplerate=44100, overlapratio=0.5): try: self.res = plt.specgram(self.data, NFFT=windowsize, Fs=samplerate, window=mlab.window_hanning, noverlap=int(windowsize * overlapratio))[0] #傅里葉變換,參數是滑動窗口大小和樣例頻率 from numpy.core.umath_tests import inner1d #計算內積 for i in xrange(len(self.res)): self.res[i] = inner1d(self.res[i], self.res[i]) #plt.plot([x for x in xrange(len(self.res))],self.res) except: raise ValueError, 'No Data for FFT' def mainfrequency(self): def compare(a, b): return int(a[0][0] < b[0][0]) sortlist = [i for i in range(len(self.res))] for i in range(len(sortlist)): sortlist[i] = (self.res[i], i) sortlist.sort(lambda x, y: cmp(sum(x[0]), sum(y[0]))) #按照內積大小結果排序 #for i in sortlist[:200]: #print i[1] return sortlist[:5] def draw(self): ''' 畫圖,爲GUI提供圖片 ''' #plt.figure(figsize=(8,4)) plt.plot([i for i in xrange(len(self.data))], self.data) plt.title(u'音頻信號波形',fontproperties='SimHei') #plt.show() plt.savefig('wave.jpg',dpi=70) plt.cla() plt.plot([i for i in xrange(len(self.res))], self.res) plt.title(u'音頻信號頻譜分析',fontproperties='SimHei') #plt.show() plt.savefig('frequency.jpg',dpi=70) if __name__ == '__main__': p = FrequencyCounter() p.loaddata('python-audio\\output2.wav') p.fft() p.draw()
PyQt4開發GUI的代碼:app
# -*- coding: utf-8 -*- from PyQt4.QtGui import * from PyQt4.QtCore import * import sys import frequency_counter2 p = frequency_counter2.FrequencyCounter() class UI(QDialog): def __init__(self, parent=None): super(UI, self).__init__(parent) self.txt = QLineEdit() self.bt_ad = QPushButton(u"選擇路徑") self.bt_a = QPushButton(u"分析") self.txtout = QTextEdit() self.pic1 = QLabel() self.pic2 = QLabel() lay = QGridLayout() #網格佈局 lay.addWidget(self.txt, 1, 1) lay.addWidget(self.bt_ad, 1, 2) lay.addWidget(self.bt_a, 2, 1, 1, 2) lay.addWidget(self.pic1, 4, 1, 3, 3) lay.addWidget(self.pic2, 7, 1, 3, 3) self.setLayout(lay) self.connect(self.bt_a, SIGNAL("clicked()"), self.analy) self.connect(self.bt_ad, SIGNAL("clicked()"), self.addr) def analy(self): #self.txtout.setText("test") pix1 = QPixmap("wave.jpg") pix2 = QPixmap("frequency.jpg") self.pic1.setPixmap(pix1) self.pic2.setPixmap(pix2) def addr(self): fname = QFileDialog.getOpenFileName(self, 'Open file') print fname p.loaddata(fname) p.fft() p.draw() self.txt.setText(fname) if __name__ == "__main__": app = QApplication(sys.argv) ui = UI() ui.setWindowTitle(u"音頻信號頻率分析") ui.show() app.exec_()
運行時界面:佈局