salut à vous...
je suis intéressé par vos codes car je me suis lancé dans le même type de programme il y a quelque mois et je l'avais mis de côté en attendant de trouver des compères...
et là je suis comblé...
mon but était également de faire des grilles d'accords pour noter des chansons : comme ici :
mais mettons cela de côté.
d'abord, votre façon d'aborder la composition des accords est un peu différente de la mienne. je vous propose de commencer par ça :
en partant d'un fichier de config basé sur l'écart des notes dans une gamme on peut reconstituer un accord en indiquant la dominante :
voici un extrait de la table que je me suis fait pour recréer les accords :
# famille | noms | harmonie |
majeur | sixième majorée, 6, M6, maj6 | 1, 5, 8, 10 |
majeur | septième majorée, maj7, Δ, Δ7, majeur7, Maj7, 7Maj, M7 | 1, 5, 8, 12 |
# l'espace est normal ;+)
majeur | majeur, , MAJ, Majeur | 1, 5, 8 |
mineur | mineur septième majorée, mΔ, -Δ, -M7, min7Δ, -Maj7 | 1, 4, 8, 12 |
mineur | mineur six bémolée, m♭6, min♭6, -♭6, minor♭6, aeolien | 1, 4, 8, 9 |
mineur | Phrygien, sus♭9, phryg, min♭2, m♭2, minor♭2, phrygien | 1, 2, 4, 8, 9 |
mineur | mineur six, m6, min6, -6 | 1, 4, 8, 10 |
mineur | mineur septième, m7, min7, -7 | 1, 4, 8, 11 |
mineur | mineur, m, - | 1, 4, 8 |
mon idée était aussi de laisser l'utilisateur pointer un manche et en sortir des possibilités de noms d'accord
par exemple accord de C (donc simple majeur composé par I III majeur et V) sur la gamme chromatique de do... ou pour ma notation : 1, 5, 8
je pense que les guitaristes ont également besoin de voir un manche pointé selon une dominante et une gamme, pour les solos voire pour les bassistes par exemple
donc mon but ultime est de faire un programme pour les guitaristes avec les grilles d'accords, les positions de doigts, les gammes,... les tablatures (à terme)
je voudrais également pouvoir faire en sorte que tous les modules ouvre, sauve ou importe, exporte depuis des fichiers textes (facilement réutilisables) pour rester dans l'idée de l'open source.
du code, du code !!!
on y va ; j'ai commencé par faire 2 manches ;
je commence par le plus simple : le manche complet (vue de dessus et corde de basse en bas)
frm_manche.py
#!/usr/bin/env python3
# -*- coding: UTF8 -*-
"""
module docstring
"""
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import Canvas
__title__ = "Ki Affiche un manche"
__author__ = 'Ury Cyril : kholo'
__license__ = 'cc'
__copyright__ = 'Creative Common 2018-2019'
__ver_major__ = 0
__ver_minor__ = 1
__ver_patch__ = 0
__ver_sub__ = ''
__version__ = "%d.%d.%d%s" % (__ver_major__, __ver_minor__,
__ver_patch__, __ver_sub__)
# from configuration import Configuration
# from guitare import TODO
class MancheGuitare(tk.Canvas):
""" """
def __init__(self, parent, *args, **kwargs):
""" """
self.parent = parent
super().__init__(*args, **kwargs)
self.configure(width=800)
self.configure(height=200)
self.configure(bg='grey')
# self.configure(bg='yellow')
## TODO : lier avec guitare
self.notes = [(1, "C"), (2, "C#"), (3, "D"), (4, "D#"), (5, "E"), (6, "F"), (7, "F#"), (8, "G"), (9, "G#"), (10, "A"), (11, "A#"), (12, "B")]
self.cordes_a_vide = ["E 3", "A 3", "D 4", "G 4", "B 4", "E 5"]
# self.notes = [(1, "do"), (2, "do#"), (3, "ré"), (4, "ré#"), (5, "mi"), (6, "fa"), (7, "fa#"), (8, "sol"), (9, "sol#"), (10, "la"), (11, "la#"), (12, "si")]
# self.cordes_a_vide = ["mi 3", "la 3", "ré 4", "sol 4", "si 4", "mi 5"]
t = [9, 11, 16, 24, 32, 42] # tirant
# print(self.notes)
Lg = 700
Tete = 50
self.create_line(Tete, 40, Lg, 40, fill="black", width=t[0]/10)
self.create_line(Tete, 60, Lg, 60, fill="black", width=t[1]/10)
self.create_line(Tete, 80, Lg, 80, fill="black", width=t[2]/10)
self.create_line(Tete, 100, Lg, 100, fill="black", width=t[3]/10)
self.create_line(Tete, 120, Lg, 120, fill="black", width=t[4]/10)
self.create_line(Tete, 140, Lg, 140, fill="black", width=t[5]/10)
## sillet de tête
self.create_line(Tete - t[0]/10/2, 40, Tete, 140 + t[5]/10/2, fill="black", width=2)
self.create_line(45, 40, 45, 140, fill="black", width=5)
## frets
self.frets = self.calculs_position_frets()
for num_f in self.frets:
x = self.frets[num_f]
self.create_line(x, 40, x, 140, fill="black", width=3)
# departx = 25
departy = 25
le_fill = "darkblue"
la_font = "Times 11 italic bold"
les_textes = ["III", "V", "VII", "IX", "XII"]
coordsX = self.calcul_placement_num_case()
for i in range(5):
self.create_text(coordsX[i], departy, fill=le_fill, font=la_font, text=les_textes[i])
## tous les points
self.points = {} # point: [[coord_x, coord_y], [corde, fret]]
self.afficher_tous_les_points()
# self.allumer(4, 1)
# self.allumer(3, 2)
# self.allumer(4, 2)
# self.allumer(5, 2)
def afficher_tous_les_points(self):
""" """
les_y = [140, 120, 100, 80, 60, 40]
a_vide = 50 - 7 ## place des points à vide
les_x = [a_vide]
cf = self.calculs_position_frets()
les_x.extend([cf[x] - a_vide / 2 for x in cf])
t = 7 ## t est rayon des points
corde = 1
m = 0
for y in les_y:
fret = 0
n = 0
for x in les_x:
le_tag = '"' + str(m) + "," + str(n) + '"'
point = self.create_oval(x-t, y-t, x+t, y+t, fill="yellow", tags=(le_tag))
self.points[point] = ([x, y], [corde, fret])
self.tag_bind(point, '<ButtonPress-1>', self.click_point)
n += 1
fret += 1
m += 1
corde += 1
def allumer(self, corde, fret):
""" sélectionne un point, l'allume et retourne le nom de la note """
le_point = [x for x in self.points if self.points[x][1] == [corde, fret]][0]
# print(le_point)
self.inverser_couleur(le_point)
""" retourne le nom de la note """
# la_note = self.coords_vers_note(le_point)
# print(la_note)
return self.coords_vers_note(le_point)
def calcul_placement_num_case(self):
""" """
retour = []
frets = self.calculs_position_frets()
for num_f in [s for s in self.frets if s < len(self.frets)]:
if num_f in [u - 1 for u in [3, 5, 7, 9, 12]]:
x1 = self.frets[num_f]
x2 = self.frets[num_f + 1]
x = ((x2 - x1) / 2) + x1
retour.append(x)
# print(retour)
return retour
def calculs_position_frets(self):
""" """
frets = {}
debut = 50
fin = 700
LG = (fin - debut)
nbreFrets = 15
x_frets = [debut]
for i in range(1, nbreFrets):
x = (int(LG / nbreFrets) * (i))
x_frets.append(x)
frets[i] = (debut + x)
#print(x_frets)
#print(frets)
return frets
def click_point(self, event):
""" """
x = self.canvasx(event.x)
y = self.canvasy(event.y)
# print(self.find_closest(x, y))
celui_la = self.find_closest(x, y)[0]
# print(celui_la)
# self.itemconfigure(celui_la, fill="blue")
# self.itemconfigure(celui_la, state="disabled")
# self.changer_couleur(celui_la, "blue")
self.inverser_couleur(celui_la)
la_note = self.coords_vers_note(celui_la)
print(la_note)
def coords_vers_note(self, coords):
""" """
#print(self.gettags(coords)[0])
corde, case = self.gettags(coords)[0].split(",")
corde = int(corde)
case = int(case)
#print("corde", corde, "case", case)
a_vide = self.cordes_a_vide[corde].split(' ')[0]
l_octave = int(self.cordes_a_vide[corde].split(' ')[1])
#print("à vide", a_vide)
num_note = [x for x in self.notes if x[1] == a_vide][0][0]
#print("num_note", num_note)
temp = num_note -1 + case
octave = 0
while temp >= 12:
temp -= 12
octave += 1
la_note = self.notes[temp][1]
l_octave = l_octave + octave
#print("la_note", la_note, l_octave)
retour = la_note + " " + str(l_octave)
return retour
def changer_couleur(self, celui_la, couleur):
self.itemconfigure(celui_la, fill=couleur)
def inverser_couleur(self, celui_la):
# print(dir(self))
# print(self.bbox(celui_la))
couleur = self.itemcget(celui_la, 'fill')
if couleur == "yellow":
# self.changer_couleur(celui_la, 'blue')
self.itemconfigure(celui_la, fill='blue')
retour = True
else:
# self.changer_couleur(celui_la, 'yellow')
self.itemconfigure(celui_la, fill='yellow')
retour = False
return retour
class Fenetre(tk.Tk):
""" """
def __init__(self, parent, *args, **kwargs):
""" """
self.parent = parent
super().__init__(*args, **kwargs)
# self.configuration = Configuration()
# c = self.configuration
self.title("Fenetre")
self.geometry("+200+300")
#********************************************
self.guitare = Guitare(self)
un_manche = MancheGuitare(self)
un_manche.grid()
#********************************************
""" pour fermer la fenetre avec le bouton escape """
self.bind('<Escape>', lambda event: self.quit())
""" la boucle de GUI """
self.mainloop()
if __name__ == "__main__":
from guitare import Guitare
Fenetre(None)
et ma class Guitare de mon module guitare.py :
class Guitare(object):
""" """
def __init__(self, parent, *args, **kwargs):
""" """
self.parent = parent
super().__init__(*args, **kwargs)
# self.configuration = Configuration()
# c = self.configuration
self.cordes_a_vide = ["E 3", "A 3", "D 4", "G 4", "B 4", "E 5"]
# self.cordes_a_vide = ["mi 3", "la 3", "ré 4", "sol 4", "si 4", "mi 5"]
self.t = [9, 11, 16, 24, 32, 42] # tirant
NB : 2/3 choses : j'ai un pote guitariste qui ne s'est jamais fait à la notation internationale donc tout devrait fonctionner en européen (do à si) et en international (C à B)
bien sur, il faut pouvoir s'adapter à l'open tuning (mais ça vous avez déjà commencé à le prendre en considération)
... pour les notes, j'utilise des numéros de gamme.
j'ai également utilisé des tailles de cordes dont je prend les tirants qui me servent à représenter le diamètre des cordes pour bien distinguer les basses des aigus.
voilà, pour commencer... si l'idée vous intéresse je vous ferais parvenir plus de code que je nettoierai à l'occasion
je vais potasser vos codes plus profondément maintenant...