SHARE
TWEET

Untitled

a guest Dec 3rd, 2019 86 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # -*- coding: utf-8 -*-
  2. # https://stackoverflow.com/questions/34522095/gui-button-hold-down-tkinter
  3. import sys
  4. if sys.version_info.major == 2 and sys.version_info.minor == 7 :
  5.     print(sys.version)
  6.     import Tkinter as tk
  7.     from Tkinter import *
  8.     import tkFileDialog as filedialog
  9. elif sys.version_info.major == 3 and sys.version_info.minor == 6 :
  10.     print(sys.version)
  11.     import tkinter as tk
  12.     from tkinter import *
  13.     from tkinter import filedialog
  14. else :
  15.     print("Your python version is : ")
  16.     print(sys.version_info.major,sys.version_info.minor)
  17.     print("... I guess it will work !")
  18.  
  19. import collections
  20.  
  21. # from Tkinter import Tk,Frame,Button,Label,Scale,IntVar
  22. from observer  import *
  23.  
  24. import subprocess
  25. import sys, re, string
  26.  
  27. from ScrolledText import *
  28. import wave
  29. from wav_audio import *
  30. import math
  31. import os
  32.  
  33.  
  34. class ScaleDuree :
  35.     def __init__(self,parent):
  36.         self.s1 = Scale(parent, from_=0.1, to=6.0,
  37.                resolution=0.1,
  38.                label='Choisir la duree de la note (en secondes):',
  39.                orient=HORIZONTAL,
  40.                length=250)
  41.         #self.s1.pack(side=TOP, expand=YES)
  42.         self.s1.grid(row=0,column=0,columnspan=2)
  43.         self.s1.set(1)
  44.     def get_duree(self):
  45.         return self.s1.get()
  46.  
  47. class ListeNotes :
  48.     def __init__(self,parent):
  49.       self.variable = StringVar(parent)
  50.       self.variable.set("A") # default value
  51.       self.s1 = OptionMenu(parent, self.variable, "C","C#","D","D#","E","F","F#","G","G#","A","A#","B")
  52.       label = Label(parent, text="Note", relief="flat", bd=4)
  53.       label.grid(row=1,column=0)
  54.       self.s1.grid(row=1,column=1)
  55.       # label.pack()
  56.       # self.s1.pack()
  57.     def get_note(self):
  58.       return self.variable.get()
  59.  
  60. class ListeOctaves :
  61.     def __init__(self,parent):
  62.       self.variable = StringVar(parent)
  63.       self.variable.set("3") # default value
  64.       self.s1 = OptionMenu(parent, self.variable, "2", "3", "4")
  65.       label = Label(parent, text="Octave", relief="flat", bd=4)
  66.       label.grid(row=2,column=0)
  67.       self.s1.grid(row=2,column=1)
  68.       # label.pack()
  69.       # self.s1.pack()
  70.     def get_octave(self):
  71.       return self.variable.get()
  72.  
  73. class ListModel(Subject):
  74.     def __init__(self, names=[]):
  75.         Subject.__init__(self)
  76.         self._data = names
  77.     def get_data(self):
  78.         return self._data
  79.     def insert(self,name):
  80.         self._data.append(name)
  81.     def delete(self):
  82.         del self._data[:]
  83.  
  84. class ListView(Observer):
  85.     def __init__(self,parent):
  86.         self.parent=parent
  87.         self.list=tk.Listbox(parent)
  88.         self.list.configure(height=7)
  89.     def update(self,model):
  90.         self.list.delete(0, "end")
  91.         for data in model.get_data():
  92.             self.list.insert("end", data)
  93.  
  94. class ControllerNotes(object):
  95.     def __init__(self,model,view,frame):
  96.         self.model,self.view = model,view
  97.         self.frame = frame    
  98.         self.scale = ScaleDuree(self.frame)
  99.         self.listNote = ListeNotes(self.frame)
  100.         self.listOctave = ListeOctaves(self.frame)
  101.         btn_generate=Button(self.frame,text="Génerer \nla note", bg ="#A7FFA4", activebackground="#99EB96", command=self.genererNote)
  102.         btn_generate.grid(row=3,column=1,pady=15)
  103.         self.msg1=StringVar()
  104.         self.label = Label(self.frame, textvariable=self.msg1, relief="flat", bd=4, fg="dark green")
  105.         self.label.grid(row=4,column=1)
  106.         self.updateSoundsList()
  107.     def genererNote(self):  
  108.         duree = self.scale.get_duree()
  109.         note = self.listNote.get_note()
  110.         octave = self.listOctave.get_octave()
  111.              
  112.         print "Note: " + note + " Octave: " + octave + " duree " + str(duree)
  113.         orderedNotes = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]
  114.         index = orderedNotes.index(note)
  115.         n = index - orderedNotes.index("A")
  116.         n = n/12.0
  117.         freq = 440.0 * pow(2,n)
  118.         freq = freq * pow(2,(int(octave) - 3))
  119.         print freq
  120.  
  121.         # change.tv.set("Création en cours")
  122.         create_note_wav(octave,note,freq,freq*2, duree)
  123.         self.msg1.set("Note " + note + octave + " créée !")
  124.         self.frame.after(1500,lambda: self.msg1.set(""))
  125.         print "done"
  126.         self.updateSoundsList()
  127.  
  128.     def updateSoundsList(self):
  129.         del self.model._data[:]
  130.         for root2, dirs, files in os.walk('GeneratedSounds/'):
  131.             for file in files:
  132.                 if file.endswith('.wav'):
  133.                     self.model._data.append(file)
  134.         self.model.notify()
  135.  
  136.  
  137.  
  138. class ControllerAjouterNote(object):
  139.     def __init__(self,model_s,view_s,model_a,view_a,frame):
  140.         self.model_s,self.view_s,self.model_a,self.view_a = model_s,view_s,model_a,view_a
  141.         self.frame = frame
  142.         btn_ajouter = Button(self.frame,text="Ajouter  --->",command=self.ajouterAccord)
  143.         btn_ajouter.grid(row=1,column=4,pady=15)  
  144.         self.msg2=StringVar()
  145.         self.label2 = Label(self.frame, textvariable=self.msg2, relief="flat", bd=4, fg="dark green")
  146.         self.label2.grid(row=2,column=4)
  147.     def ajouterAccord(self):
  148.         empty=True
  149.         for index in self.view_s.list.curselection():
  150.             empty=False
  151.             alreadyIn = False
  152.             for note in self.model_a._data:
  153.                 if self.model_s._data[int(index)] == note:
  154.                     alreadyIn = True
  155.             if alreadyIn == False and len(self.model_a._data)<3:
  156.                 self.model_a.insert(self.model_s._data[int(index)])
  157.                 self.msg2.set("Note ajoutée !")
  158.                 self.label2.config(fg="dark green")
  159.                 self.frame.after(1500,lambda: self.msg2.set(""))
  160.             elif alreadyIn == True:
  161.                 self.msg2.set("Note déjà ajoutée")
  162.                 self.label2.config(fg="red")
  163.                 self.frame.after(1500,lambda: self.msg2.set(""))
  164.             elif len(self.model_a._data)>=3:
  165.                 self.msg2.set("Il y a déjà 3 notes")
  166.                 self.label2.config(fg="red")
  167.                 self.frame.after(1500,lambda: self.msg2.set(""))
  168.         if empty:
  169.             self.msg2.set("Veuillez selectionner\n une note !")
  170.             self.label2.config(fg="red")
  171.             self.frame.after(1500,lambda: self.msg2.set(""))
  172.         self.model_a.notify()
  173.  
  174.  
  175. class ControllerCreerAccord(object):
  176.     def __init__(self,model_a,view_a,model_c,view_c,frame):
  177.         self.model_a,self.view_a,self.model_c,self.view_c = model_a,view_a,model_c,view_c
  178.         self.frame = frame
  179.         btn_creerAccord = Button(self.frame,text="Créer l'accord", bg ="#A7FFA4", activebackground="#99EB96",command=self.creerAccord)
  180.         btn_creerAccord.grid(row=3,column=5)
  181.         btn_refresh = Button(self.frame,text="Clear list",command=self.refresh)
  182.         btn_refresh.grid(row=3,column=6)
  183.         self.msg3=StringVar()
  184.         self.label3 = Label(self.frame, textvariable=self.msg3, relief="flat", bd=4, fg="red")
  185.         self.label3.grid(row=4,column=5,columnspan=2)
  186.         self.updateChordsList()
  187.     def creerAccord(self):
  188.         if len(self.model_a._data) == 3:
  189.             data1,framerate1 = open_wav('GeneratedSounds/'+self.model_a._data[0])
  190.             data2,framerate2 = open_wav('GeneratedSounds/'+self.model_a._data[1])
  191.             data3,framerate3 = open_wav('GeneratedSounds/'+self.model_a._data[2])
  192.             data = [] # liste des échantillons de l'accord
  193.             for i in range(len(data1)):
  194.                 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  
  195.  
  196.             save_wav('Chords/'+self.model_a._data[0].replace('.wav','')+self.model_a._data[1].replace('.wav','')+self.model_a._data[2],data,framerate1)
  197.             self.model_a.delete()
  198.             self.model_a.notify()
  199.             #self.view_a.update(self.model_a)
  200.             self.msg3.set("Accord créé !")
  201.             self.label3.config(fg="dark green")
  202.             self.frame.after(1500,lambda: self.msg3.set(""))
  203.             self.updateChordsList()
  204.         else :
  205.             self.msg3.set("Veuillez selectionner 3 notes")
  206.             self.label3.config(fg="red")
  207.             self.frame.after(1500,lambda: self.msg3.set(""))
  208.     def refresh(self):
  209.         self.model_a.delete()
  210.         self.model_a.notify()
  211.         #self.view_a.update(self.model_a)
  212.     def updateChordsList(self):
  213.         #del self.chords[:]
  214.         self.model_c.delete()
  215.         for root2, dirs, files in os.walk('Chords/'):
  216.             for file in files:
  217.                 if file.endswith('.wav'):
  218.                     self.model_c.insert(file)
  219.         self.view_c.update(self.model_c)
  220.  
  221.  
  222.  
  223. class changeNoteView :
  224.     def __init__(self,parent) :
  225.         self.parent=parent
  226.         self.frame = tk.Frame(self.parent)    
  227.  
  228.         label_note = Label(self.frame, text="Notes", relief="flat", bd=4)
  229.         self.sounds = []
  230.         self.model_sounds = ListModel(self.sounds)
  231.         self.view_sounds = ListView(self.frame)
  232.         self.view_sounds.update(self.model_sounds)
  233.         self.model_sounds.attach(self.view_sounds)
  234.         self.controlleur_sounds = ControllerNotes(self.model_sounds, self.view_sounds, self.frame)
  235.         btn_play_sound= Button(self.frame,text="Play",command=self.play_sound)
  236.        
  237.         label_note.grid(row=0,column=2)
  238.         self.view_sounds.list.grid(row=0,column=2,rowspan=4,columnspan=2,padx=25)
  239.         btn_play_sound.grid(row=3,column=2)        
  240.  
  241.  
  242.         label_accord = Label(self.frame, text="Creation d'accords", relief="flat", bd=4)
  243.         label_accord.grid(row=0,column=5)
  244.         self.accords = []
  245.         self.model_accords = ListModel(self.accords)
  246.         self.view_accords = ListView(self.frame)
  247.         self.view_accords.list.grid(row=0,column=5,rowspan=4,columnspan=2,padx=25)
  248.         self.view_accords.update(self.model_accords)
  249.         self.model_accords.attach(self.view_accords)
  250.         self.controllerBtnAjout = ControllerAjouterNote(self.model_sounds, self.view_sounds, self.model_accords, self.view_accords,self.frame)
  251.        
  252.        
  253.  
  254.         label_chords = Label(self.frame, text = "Accords",relief="flat",bd=4)
  255.         label_chords.grid(row = 0,column=7)
  256.         self.chords = []
  257.         self.model_chords = ListModel(self.chords)
  258.         self.view_chords = ListView(self.frame)
  259.         # self.updateChordsList()
  260.         self.view_chords.list.grid(row=0,column=7,rowspan=4,columnspan=2,padx=25)
  261.         self.view_chords.update(self.model_chords)
  262.         self.model_chords.attach(self.view_chords)
  263.         self.controllerCreerAcc = ControllerCreerAccord(self.model_accords, self.view_accords, self.model_chords, self.view_chords,self.frame)
  264.         btn_play_chord = Button(self.frame,text="Play",command=self.play_chord)
  265.         btn_play_chord.grid(row=3,column=7)
  266.  
  267.  
  268.         self.frame.pack()
  269.        
  270.  
  271.     # def updateSoundsList(self):
  272.     #     del self.sounds[:]
  273.     #     for root2, dirs, files in os.walk('GeneratedSounds/'):
  274.     #         for file in files:
  275.     #             if file.endswith('.wav'):
  276.     #                 self.sounds.append(file)
  277.     #     self.view_sounds.update(self.model_sounds)
  278.  
  279.    
  280.  
  281.  
  282.     def play_sound(self):
  283.         for index in self.view_sounds.list.curselection():
  284.             subprocess.call(["aplay","GeneratedSounds/"+self.model_sounds._data[int(index)]])
  285.  
  286.     def play_chord(self):
  287.         for index in self.view_chords.list.curselection():
  288.             subprocess.call(["aplay","Chords/"+self.model_chords._data[int(index)]])
  289.        
  290.  
  291.     # def genererNote(self):  
  292.     #   duree = self.scale.get_duree()
  293.     #   note = self.listNote.get_note()
  294.     #   octave = self.listOctave.get_octave()
  295.            
  296.     #   print "Note: " + note + " Octave: " + octave + " duree " + str(duree)
  297.     #   orderedNotes = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]
  298.     #   index = orderedNotes.index(note)
  299.     #   n = index - orderedNotes.index("A")
  300.     #   n = n/12.0
  301.     #   freq = 440.0 * pow(2,n)
  302.     #   freq = freq * pow(2,(int(octave) - 3))
  303.     #   print freq
  304.  
  305.     #   # change.tv.set("Création en cours")
  306.     #   create_note_wav(octave,note,freq,freq*2, duree)
  307.     #   self.msg1.set("Note " + note + octave + " créée !")
  308.     #   self.frame.after(1500,lambda: self.msg1.set(""))
  309.     #   print "done"
  310.     #   self.updateSoundsList()
  311.      
  312.  
  313. def create_note_wav(degree,name,left_frequency,right_frequency, duration) :
  314.     if type(degree) != str :
  315.         degree=str(degree)
  316.     save_path = 'GeneratedSounds/'
  317.     file= os.path.join(save_path, name+degree+".wav")
  318.     sound=wave.open(file,'w')
  319.     nb_channels = 2    # stéreo
  320.     nb_bytes = 1       # taille d'un échantillon : 1 octet = 8 bits
  321.     sampling = 44100   # fréquence d'échantillonnage
  322.     left_level = 1     # niveau canal de gauche (0 à 1) ? '))
  323.     right_level= 0.5    # niveau canal de droite (0 à 1) ? '))
  324.     nb_samples = int(duration*sampling)
  325.     params = (nb_channels,nb_bytes,sampling,nb_samples,'NONE','not compressed')
  326.     sound.setparams(params)    # création de l'en-tête (44 octets)
  327.  
  328.     # niveau max dans l'onde positive : +1 -> 255 (0xFF)
  329.     # niveau max dans l'onde négative : -1 ->   0 (0x00)
  330.     # niveau sonore nul :                0 -> 127.5 (0x80 en valeur arrondi)
  331.  
  332.     left_magnitude = 127.5*left_level
  333.     right_magnitude= 127.5*right_level
  334.  
  335.     for i in range(0,nb_samples):
  336.         # canal gauche
  337.         # 127.5 + 0.5 pour arrondir à l'entier le plus proche
  338.         left_value = wave.struct.pack('B',int(128.0 + left_magnitude*math.sin(2.0*math.pi*left_frequency*i/sampling)))
  339.         # canal droit
  340.         right_value = wave.struct.pack('B',int(128.0 + right_magnitude*math.sin(2.0*math.pi*right_frequency*i/sampling)))
  341.         sound.writeframes(left_value + right_value) # écriture frame
  342.  
  343.     sound.close()
  344.  
  345.  
  346.  
  347. if __name__ == "__main__" :
  348.     root = tk.Tk()
  349.     root.geometry("1000x270")
  350.     root.title("Generation de note")
  351.     change = changeNoteView(root)
  352.     root.mainloop()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top