■
めげずにFFT表示を改善する。…いや、ずらして仮想3Dにしただけだけど。
import Tkinter import tkFileDialog import wave, math, struct import scipy.fftpack # def wavePrint(fileName): # f = wave.open(fileName,'r') # (nchannels, sampwidth, framerate, nframes, comptype, compname) = f.getparams() # print (nchannels, sampwidth, framerate, nframes, comptype, compname) # frames = [] # for ii in range(nframes): # frames.extend(struct.unpack('h',f.readframes(1))) # print frames class waveFileRead: def __init__(self): pass def open(self,fileName): self.f = wave.open(fileName,'r') (nchannels, sampwidth, framerate, nframes, comptype, compname) = self.f.getparams() self.sampwidth = self.f.getsampwidth() print (nchannels, sampwidth, framerate, nframes, comptype, compname,'%dh' % nframes) # print "pos:",self.f.tell() def read(self,nframes): return struct.unpack('%dh' % (nframes*self.sampwidth/2), self.f.readframes(nframes)) def pos(self,pos): return self.f.setpos(pos) def nframes(self): return self.f.getnframes() class fftViewer: def __init__(self): self.window = Tkinter.Tk() self.width = 640 self.height = 480 self.canvas = Tkinter.Canvas(self.window,bg="white", width=self.width,height=self.height) self.canvas.pack() self.scale = Tkinter.Scale(self.window,command=self.scaleChanged, orient=Tkinter.HORIZONTAL) self.scale.pack(side=Tkinter.LEFT) self.btnOpenFile = Tkinter.Button(self.window,text="open",command=self.clickOpenFile) self.btnOpenFile.pack(side=Tkinter.RIGHT) self.btnPlay = Tkinter.Button(self.window,text="play",command=self.clickPlay) self.btnPlay.pack(side=Tkinter.RIGHT) self.objects = [] self.autoFlag = False self.window.mainloop() def scaleChanged(self,pos): self.paintCanvas() def clickPlay(self): self.autoFlag = not self.autoFlag if self.autoFlag: self.window.after(10,self.autoPlay) def autoPlay(self): if self.autoFlag: self.scale.set(self.scale.get()+self.width) self.window.after(100,self.autoPlay) def clickOpenFile(self): fileName = tkFileDialog.askopenfilename() self.w = waveFileRead() self.w.open(fileName) self.scale.set(0) self.scale.configure(from_=0,to=self.w.nframes()) self.paintCanvas() def paintCanvas(self): # for item in self.objects: # self.canvas.delete(item) # self.objects = [] if len(self.objects) > self.height/10: waste = self.objects.pop(0) for item in waste: self.canvas.delete(item) for items in self.objects: for item in items: self.canvas.move(item,10,-10) frame = self.scale.get() self.w.pos(frame) sampwidth = self.w.sampwidth / 2 x = 0 y = 0 objects = [] frames = scipy.fftpack.fftshift( scipy.fftpack.rfft(self.w.read(self.width/sampwidth))) for f in frames: cy = self.height - abs(f/50000)# - (lineNum*10) objects.append(self.canvas.create_line(x,y, x+1,cy, fill='black',width=1)) x,y = x+1,cy self.objects.append(objects) if __name__=='__main__': fftViewer()