Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- # https://stackoverflow.com/questions/34522095/gui-button-hold-down-tkinter
- import sys
- if sys.version_info.major == 2 and sys.version_info.minor == 7 :
- print(sys.version)
- import Tkinter as tk
- from Tkinter import *
- import tkFileDialog as filedialog
- elif sys.version_info.major == 3 and sys.version_info.minor == 6 :
- print(sys.version)
- import tkinter as tk
- from tkinter import *
- from tkinter import filedialog
- else :
- print("Your python version is : ")
- print(sys.version_info.major,sys.version_info.minor)
- print("... I guess it will work !")
- import collections
- # from Tkinter import Tk,Frame,Button,Label,Scale,IntVar
- from observer import *
- import subprocess
- import sys, re, string
- from ScrolledText import *
- import wave
- from wav_audio import *
- import math
- import os
- class ScaleDuree :
- def __init__(self,parent):
- self.s1 = Scale(parent, from_=0.1, to=6.0,
- resolution=0.1,
- label='Choisir la duree de la note (en secondes):',
- orient=HORIZONTAL,
- length=250)
- #self.s1.pack(side=TOP, expand=YES)
- self.s1.grid(row=0,column=0,columnspan=2)
- self.s1.set(1)
- def get_duree(self):
- return self.s1.get()
- class ListeNotes :
- def __init__(self,parent):
- self.variable = StringVar(parent)
- self.variable.set("A") # default value
- self.s1 = OptionMenu(parent, self.variable, "C","C#","D","D#","E","F","F#","G","G#","A","A#","B")
- label = Label(parent, text="Note", relief="flat", bd=4)
- label.grid(row=1,column=0)
- self.s1.grid(row=1,column=1)
- # label.pack()
- # self.s1.pack()
- def get_note(self):
- return self.variable.get()
- class ListeOctaves :
- def __init__(self,parent):
- self.variable = StringVar(parent)
- self.variable.set("3") # default value
- self.s1 = OptionMenu(parent, self.variable, "2", "3", "4")
- label = Label(parent, text="Octave", relief="flat", bd=4)
- label.grid(row=2,column=0)
- self.s1.grid(row=2,column=1)
- # label.pack()
- # self.s1.pack()
- def get_octave(self):
- return self.variable.get()
- class ListModel(Subject):
- def __init__(self, names=[]):
- Subject.__init__(self)
- self._data = names
- def get_data(self):
- return self._data
- def insert(self,name):
- self._data.append(name)
- def delete(self):
- del self._data[:]
- class ListView(Observer):
- def __init__(self,parent):
- self.parent=parent
- self.list=tk.Listbox(parent)
- self.list.configure(height=7)
- def update(self,model):
- self.list.delete(0, "end")
- for data in model.get_data():
- self.list.insert("end", data)
- class ControllerNotes(object):
- def __init__(self,model,view,frame):
- self.model,self.view = model,view
- self.frame = frame
- self.scale = ScaleDuree(self.frame)
- self.listNote = ListeNotes(self.frame)
- self.listOctave = ListeOctaves(self.frame)
- btn_generate=Button(self.frame,text="Génerer \nla note", bg ="#A7FFA4", activebackground="#99EB96", command=self.genererNote)
- btn_generate.grid(row=3,column=1,pady=15)
- self.msg1=StringVar()
- self.label = Label(self.frame, textvariable=self.msg1, relief="flat", bd=4, fg="dark green")
- self.label.grid(row=4,column=1)
- self.updateSoundsList()
- def genererNote(self):
- duree = self.scale.get_duree()
- note = self.listNote.get_note()
- octave = self.listOctave.get_octave()
- print "Note: " + note + " Octave: " + octave + " duree " + str(duree)
- orderedNotes = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]
- index = orderedNotes.index(note)
- n = index - orderedNotes.index("A")
- n = n/12.0
- freq = 440.0 * pow(2,n)
- freq = freq * pow(2,(int(octave) - 3))
- print freq
- # change.tv.set("Création en cours")
- create_note_wav(octave,note,freq,freq*2, duree)
- self.msg1.set("Note " + note + octave + " créée !")
- self.frame.after(1500,lambda: self.msg1.set(""))
- print "done"
- self.updateSoundsList()
- def updateSoundsList(self):
- del self.model._data[:]
- for root2, dirs, files in os.walk('GeneratedSounds/'):
- for file in files:
- if file.endswith('.wav'):
- self.model._data.append(file)
- self.model.notify()
- class ControllerAjouterNote(object):
- def __init__(self,model_s,view_s,model_a,view_a,frame):
- self.model_s,self.view_s,self.model_a,self.view_a = model_s,view_s,model_a,view_a
- self.frame = frame
- btn_ajouter = Button(self.frame,text="Ajouter --->",command=self.ajouterAccord)
- btn_ajouter.grid(row=1,column=4,pady=15)
- self.msg2=StringVar()
- self.label2 = Label(self.frame, textvariable=self.msg2, relief="flat", bd=4, fg="dark green")
- self.label2.grid(row=2,column=4)
- def ajouterAccord(self):
- empty=True
- for index in self.view_s.list.curselection():
- empty=False
- alreadyIn = False
- for note in self.model_a._data:
- if self.model_s._data[int(index)] == note:
- alreadyIn = True
- if alreadyIn == False and len(self.model_a._data)<3:
- self.model_a.insert(self.model_s._data[int(index)])
- self.msg2.set("Note ajoutée !")
- self.label2.config(fg="dark green")
- self.frame.after(1500,lambda: self.msg2.set(""))
- elif alreadyIn == True:
- self.msg2.set("Note déjà ajoutée")
- self.label2.config(fg="red")
- self.frame.after(1500,lambda: self.msg2.set(""))
- elif len(self.model_a._data)>=3:
- self.msg2.set("Il y a déjà 3 notes")
- self.label2.config(fg="red")
- self.frame.after(1500,lambda: self.msg2.set(""))
- if empty:
- self.msg2.set("Veuillez selectionner\n une note !")
- self.label2.config(fg="red")
- self.frame.after(1500,lambda: self.msg2.set(""))
- self.model_a.notify()
- class ControllerCreerAccord(object):
- def __init__(self,model_a,view_a,model_c,view_c,frame):
- self.model_a,self.view_a,self.model_c,self.view_c = model_a,view_a,model_c,view_c
- self.frame = frame
- btn_creerAccord = Button(self.frame,text="Créer l'accord", bg ="#A7FFA4", activebackground="#99EB96",command=self.creerAccord)
- btn_creerAccord.grid(row=3,column=5)
- btn_refresh = Button(self.frame,text="Clear list",command=self.refresh)
- btn_refresh.grid(row=3,column=6)
- self.msg3=StringVar()
- self.label3 = Label(self.frame, textvariable=self.msg3, relief="flat", bd=4, fg="red")
- self.label3.grid(row=4,column=5,columnspan=2)
- self.updateChordsList()
- def creerAccord(self):
- if len(self.model_a._data) == 3:
- data1,framerate1 = open_wav('GeneratedSounds/'+self.model_a._data[0])
- data2,framerate2 = open_wav('GeneratedSounds/'+self.model_a._data[1])
- data3,framerate3 = open_wav('GeneratedSounds/'+self.model_a._data[2])
- data = [] # liste des échantillons de l'accord
- for i in range(len(data1)):
- data.append((1.0/3.0)*(data1[i]+data2[i]+data3[i])) # calcul de la moyenne de chacun des échantillons de même index issus des trois listes
- save_wav('Chords/'+self.model_a._data[0].replace('.wav','')+self.model_a._data[1].replace('.wav','')+self.model_a._data[2],data,framerate1)
- self.model_a.delete()
- self.model_a.notify()
- #self.view_a.update(self.model_a)
- self.msg3.set("Accord créé !")
- self.label3.config(fg="dark green")
- self.frame.after(1500,lambda: self.msg3.set(""))
- self.updateChordsList()
- else :
- self.msg3.set("Veuillez selectionner 3 notes")
- self.label3.config(fg="red")
- self.frame.after(1500,lambda: self.msg3.set(""))
- def refresh(self):
- self.model_a.delete()
- self.model_a.notify()
- #self.view_a.update(self.model_a)
- def updateChordsList(self):
- #del self.chords[:]
- self.model_c.delete()
- for root2, dirs, files in os.walk('Chords/'):
- for file in files:
- if file.endswith('.wav'):
- self.model_c.insert(file)
- self.view_c.update(self.model_c)
- class changeNoteView :
- def __init__(self,parent) :
- self.parent=parent
- self.frame = tk.Frame(self.parent)
- label_note = Label(self.frame, text="Notes", relief="flat", bd=4)
- self.sounds = []
- self.model_sounds = ListModel(self.sounds)
- self.view_sounds = ListView(self.frame)
- self.view_sounds.update(self.model_sounds)
- self.model_sounds.attach(self.view_sounds)
- self.controlleur_sounds = ControllerNotes(self.model_sounds, self.view_sounds, self.frame)
- btn_play_sound= Button(self.frame,text="Play",command=self.play_sound)
- label_note.grid(row=0,column=2)
- self.view_sounds.list.grid(row=0,column=2,rowspan=4,columnspan=2,padx=25)
- btn_play_sound.grid(row=3,column=2)
- label_accord = Label(self.frame, text="Creation d'accords", relief="flat", bd=4)
- label_accord.grid(row=0,column=5)
- self.accords = []
- self.model_accords = ListModel(self.accords)
- self.view_accords = ListView(self.frame)
- self.view_accords.list.grid(row=0,column=5,rowspan=4,columnspan=2,padx=25)
- self.view_accords.update(self.model_accords)
- self.model_accords.attach(self.view_accords)
- self.controllerBtnAjout = ControllerAjouterNote(self.model_sounds, self.view_sounds, self.model_accords, self.view_accords,self.frame)
- label_chords = Label(self.frame, text = "Accords",relief="flat",bd=4)
- label_chords.grid(row = 0,column=7)
- self.chords = []
- self.model_chords = ListModel(self.chords)
- self.view_chords = ListView(self.frame)
- # self.updateChordsList()
- self.view_chords.list.grid(row=0,column=7,rowspan=4,columnspan=2,padx=25)
- self.view_chords.update(self.model_chords)
- self.model_chords.attach(self.view_chords)
- self.controllerCreerAcc = ControllerCreerAccord(self.model_accords, self.view_accords, self.model_chords, self.view_chords,self.frame)
- btn_play_chord = Button(self.frame,text="Play",command=self.play_chord)
- btn_play_chord.grid(row=3,column=7)
- self.frame.pack()
- # def updateSoundsList(self):
- # del self.sounds[:]
- # for root2, dirs, files in os.walk('GeneratedSounds/'):
- # for file in files:
- # if file.endswith('.wav'):
- # self.sounds.append(file)
- # self.view_sounds.update(self.model_sounds)
- def play_sound(self):
- for index in self.view_sounds.list.curselection():
- subprocess.call(["aplay","GeneratedSounds/"+self.model_sounds._data[int(index)]])
- def play_chord(self):
- for index in self.view_chords.list.curselection():
- subprocess.call(["aplay","Chords/"+self.model_chords._data[int(index)]])
- # def genererNote(self):
- # duree = self.scale.get_duree()
- # note = self.listNote.get_note()
- # octave = self.listOctave.get_octave()
- # print "Note: " + note + " Octave: " + octave + " duree " + str(duree)
- # orderedNotes = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]
- # index = orderedNotes.index(note)
- # n = index - orderedNotes.index("A")
- # n = n/12.0
- # freq = 440.0 * pow(2,n)
- # freq = freq * pow(2,(int(octave) - 3))
- # print freq
- # # change.tv.set("Création en cours")
- # create_note_wav(octave,note,freq,freq*2, duree)
- # self.msg1.set("Note " + note + octave + " créée !")
- # self.frame.after(1500,lambda: self.msg1.set(""))
- # print "done"
- # self.updateSoundsList()
- def create_note_wav(degree,name,left_frequency,right_frequency, duration) :
- if type(degree) != str :
- degree=str(degree)
- save_path = 'GeneratedSounds/'
- file= os.path.join(save_path, name+degree+".wav")
- sound=wave.open(file,'w')
- nb_channels = 2 # stéreo
- nb_bytes = 1 # taille d'un échantillon : 1 octet = 8 bits
- sampling = 44100 # fréquence d'échantillonnage
- left_level = 1 # niveau canal de gauche (0 à 1) ? '))
- right_level= 0.5 # niveau canal de droite (0 à 1) ? '))
- nb_samples = int(duration*sampling)
- params = (nb_channels,nb_bytes,sampling,nb_samples,'NONE','not compressed')
- sound.setparams(params) # création de l'en-tête (44 octets)
- # niveau max dans l'onde positive : +1 -> 255 (0xFF)
- # niveau max dans l'onde négative : -1 -> 0 (0x00)
- # niveau sonore nul : 0 -> 127.5 (0x80 en valeur arrondi)
- left_magnitude = 127.5*left_level
- right_magnitude= 127.5*right_level
- for i in range(0,nb_samples):
- # canal gauche
- # 127.5 + 0.5 pour arrondir à l'entier le plus proche
- left_value = wave.struct.pack('B',int(128.0 + left_magnitude*math.sin(2.0*math.pi*left_frequency*i/sampling)))
- # canal droit
- right_value = wave.struct.pack('B',int(128.0 + right_magnitude*math.sin(2.0*math.pi*right_frequency*i/sampling)))
- sound.writeframes(left_value + right_value) # écriture frame
- sound.close()
- if __name__ == "__main__" :
- root = tk.Tk()
- root.geometry("1000x270")
- root.title("Generation de note")
- change = changeNoteView(root)
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement