Advertisement
Guest User

Untitled

a guest
Dec 3rd, 2019
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.98 KB | None | 0 0
  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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement