■
とりあえず、マウスをクリックすると音符ができて、playできるところまで。
…もうすこしスマートなプログラムにしたい。
…暑くってやる気が起きない。
#!/usr/bin/env python import Tkinter import math import sndPlay class scorePlayer: def __init__(self): self.width = 800 self.height = 200 self.window = Tkinter.Tk() self.canvas = Tkinter.Canvas(self.window,bg='white', width=self.width,height=self.height) self.canvas.bind("<Motion>",self.motionCanvas) self.canvas.bind("<ButtonPress-1>",self.press1Canvas) freqMap = [{'inc':3,'color':'white'}, # C {'inc':5,'color':'white'}, # D {'inc':7,'color':'black'}, # E {'inc':8,'color':'white'}, # F {'inc':10,'color':'black'}, # G {'inc':12,'color':'white'}, # A {'inc':14,'color':'black'}, # B {'inc':15,'color':'white'}, # C {'inc':17,'color':'black'}, # D {'inc':19,'color':'white'}, # E {'inc':20,'color':'black'}, # F {'inc':22,'color':'white'}, # G {'inc':24,'color':'white'}, # A ] inc = math.pow(2,1.0/12) A = 440 self.toneMap = [{'index':ii,'freq':math.pow(inc,freqMap[ii]['inc'])*A,'color':freqMap[ii]['color']} for ii in range(len(freqMap))] self.toneMap.reverse() self.notes = [] self.canvas.pack() self.currentNote = None self.xStart = 40 self.currentX = 0 self.xInterval = 30 self.scoreYInterval = 10 self.noteWidth,self.noteHeight = 15,8 self.paint() self.playButton = Tkinter.Button(self.window,text="play", command=self.play) self.clearButton = Tkinter.Button(self.window,text='clear', command=self.clear) self.playButton.pack(side=Tkinter.RIGHT) self.clearButton.pack(side=Tkinter.RIGHT) self.window.mainloop() def clear(self): for note in self.notes: self.canvas.delete(note['index']) self.notes = [] self.currentX = 0 def play(self): s = sndPlay.sndPlay() s.A = 440 for note in self.notes: print note # self.canvas.itemconfigure(note['index'],outline='red') s.addWave(note['tone']['freq'],0.5) s.addWave(0,0.1) # self.canvas.itemconfigure(note['index'],outline='black') s.closeFile() def convertYtoTone(self,y): interval = self.scoreYInterval / 2 for tone in self.toneMap: jj = tone['y'] if jj-interval < y < jj+interval: return tone return None def press1Canvas(self,event): width,height = self.noteWidth,self.noteHeight tone = self.convertYtoTone(event.y) if tone==None: return y = tone['y'] x = self.currentX*self.xInterval+self.xStart index = self.canvas.create_oval(x-width/2,y-height/2, x+width/2,y+height/2, fill='black', width=2) self.currentX = self.currentX + 1 self.notes.append({'tone':tone,'index':index}) def motionCanvas(self,event): width,height = self.noteWidth,self.noteHeight x = event.x tone = self.convertYtoTone(event.y) if tone==None: return y = tone['y'] if( self.currentNote == None ): self.currentNote = self.canvas.create_oval(x-width/2,y-height/2, x+width/2,y+height/2, outline='gray', fill='gray', width=2) else: self.canvas.coords(self.currentNote, x-width/2,y-height/2, x+width/2,y+height/2) def paint(self): xMargin = 30 yMargin = 30 scoreYInterval = self.scoreYInterval for ii in range(len(self.toneMap)): sx = xMargin ex = self.width - xMargin sy = ey = yMargin + scoreYInterval/2*ii self.canvas.create_line(sx,sy,ex,ey,fill=self.toneMap[ii]['color'],width=1) self.toneMap[ii]['y'] = sy if __name__ == '__main__': scorePlayer()