めげずに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()