diff --git a/musique/exercice.py b/musique/exercice.py index 915c9e26598ecffe905cf93ea5f7813899d28ab3..f4176e4e9805cd6273f0def65004b2917524fa6c 100644 --- a/musique/exercice.py +++ b/musique/exercice.py @@ -122,17 +122,37 @@ class GenerateurExercice(GammeTemperee): ds = self.durees(partitions) result += "\\begin{table}[H]\n\centering\n" - result += "\\begin{tabular}{|c|c|c|c|}\n" + result += "\\begin{tabular}{|l" + "".join(["|c" for d in ds ]) + "|}\n" result += "\\hline\n" - result += "Graphique & \\textbf{Longueur} (cm) & \\textbf{Durée} (s) & \\textbf{Tête de note} \\\\ \n" - result += "\\hline\n" - + + result += "\\textbf{Graphique} " for duree in ds: + result += "& " result += "\\begin{tikzpicture}[]" result += self.noteGraphique(0, 0, duree, 0) result += "\\end{tikzpicture}" - result += "& " + '{0:.2f}'.format(self.dureeEnCm(duree)) + " & " + '{0:.2f}'.format(duree) + "&" + self.nomDuree(duree) + "\\\\\n" - result += "\\hline\n" + result += "\\\\ \n" + result += "\\hline\n" + + + result += "\\textbf{Longueur} (cm) " + for duree in ds: + result += "& " + '{0:.2f}'.format(self.dureeEnCm(duree)).replace(".", ",") + result += "\\\\ \n" + result += "\\hline\n" + + result += "\\textbf{Durée} (s)" + for duree in ds: + result += "& " + '{0:.2f}'.format(duree).replace(".", ",") + result += "\\\\ \n" + result += "\\hline\n" + + result += "\\textbf{Tête de note}" + for duree in ds: + result += "& " + self.nomDuree(duree) + result += "\\\\ \n" + result += "\\hline\n" + result += "\\end{tabular}\n" result += "\\caption{Table des durées}\n" @@ -146,22 +166,22 @@ class GenerateurExercice(GammeTemperee): # on ne va utiliser que la première partition partition = partitions[0] - result = "" + result = "\\renewcommand{\\arraystretch}{1.5}" result += "\\begin{table}[H]\n\centering\n" result += "\\begin{tabular}{|c||c|c||c|c|}\n" result += "\\hline\n" result += " & \multicolumn{2}{c||}{Transcription} & \multicolumn{2}{c|}{Codage} \\\\ \n" - result += "\\textbf{Note} & \\textbf{Fréquence} (Hz) & \\textbf{Longueur} (cm) &\\textbf{Note} & \\textbf{Durée} \\\\ \n" + result += "\\textbf{Note} & \\textbf{Fréquence} (Hz) & \\textbf{Durée} (s) &\qquad\\textbf{Note}\qquad~ & \qquad\\textbf{Tête}\qquad~ \\\\ \n" result += "\\hline \n" for i, note in enumerate(partition): result += str(i + 1) + " & " if solution: if isinstance(note[0], float): - result += str(int(round(note[0]))) + " & " + '{0:.2f}'.format(note[1]) + " & " + result += str(int(round(note[0]))) + " & " + '{0:.2f}'.format(note[1]).replace(".", ",") + " & " result += self.frequenceToLaTeX(note[0]) + "& " + self.nomDuree(note[1]) + " \\\\\n" result += "\\hline\n" else: - result += ', '.join(['{0:.2f}'.format(n) for n in note[0]]) + " & " + '{0:.2f}'.format(note[1]) + result += ', '.join(['{0:.2f}'.format(n) for n in note[0]]) + " & " + '{0:.2f}'.format(note[1]).replace(".", ",") result += " & " + ', '.join([self.frequenceToLaTeX(n) for n in note[0]]) + " & " + self.nomDuree(note[1]) + " \\\\\n" result += "\\hline\n" else: @@ -205,15 +225,19 @@ class GenerateurExercice(GammeTemperee): def finExerciceSpectrogramme(self, partitions): result = "\n" - result += "\\cleardoublepage\n" + result += "~\\clearpage\n" + + # on écrit le tableau de durées result += self.tableauDurees(partitions) + # on écrit le tableau des fréquences result += self.tableauFrequences(partitions) - result += "\\cleardoublepage\n" + result += "~\\clearpage\n" + # on écrit le tableau de l'exercice à remplir result += "Remplir le tableau par lecture graphique: " @@ -251,6 +275,7 @@ class GenerateurExercice(GammeTemperee): # à l'horodatage donné def accordSpectrogrammePartition(self, accord, horodatage, couleur): if isinstance(accord[0], float): + print "duree", accord[1], self.nomDuree(accord[1]) return self.noteSpectrogrammePartition(accord[0], accord[1], horodatage, couleur) else: return ''.join([self.noteSpectrogrammePartition(note, accord[1], horodatage, couleur) for note in accord[0]]) @@ -293,7 +318,7 @@ class GenerateurExercice(GammeTemperee): return result def graduationOrdonnees(self, partitions): - frequences = self.notesDansIntervalle(self.minFrequence(partitions), self.maxFrequence(partitions)) + frequences = self.notesDansPartition(partitions) result = "" @@ -305,6 +330,42 @@ class GenerateurExercice(GammeTemperee): return result + def lignesVerticales(self): + result = "" + + espace = self.doublecroche + + nbsteps = int(self.duree / espace) + 1 + + for i in range(0, nbsteps): + h = i * espace + hinc = self.dureeEnCm(h + self.margeDuree) + + if i % 4 == 0: + result += "\draw[lightgray, ultra thin] (" + str(hinc) + ", 0) -- "; + else: + result += "\draw[lightgray!30, ultra thin] (" + str(hinc) + ", 0) -- "; + result += "(" + str(hinc) + ", " + str(self.hauteur) + ");\n"; + return result + + def lignesHorizontales(self, partitions): + + result = "" + + frequences = self.notesDansIntervalle(self.minFrequence(partitions), self.maxFrequence(partitions), True) + for frequence in frequences: + finc = self.frequenceEnCm(frequence) + result += "\draw[lightgray, ultra thin] (0, " + str(finc) + ") -- "; + result += "(" + str(self.largeur) + ", " + str(finc) + ");\n"; + + frequences = self.notesDansIntervalle(self.minFrequence(partitions), self.maxFrequence(partitions)) + for frequence in frequences: + finc = self.frequenceEnCm(frequence) + result += "\draw[lightgray!30, dashed, ultra thin] (0, " + str(finc) + ") -- "; + result += "(" + str(self.largeur) + ", " + str(finc) + ");\n"; + + return result + # cette fonction écrit le spectrogramme simplifié correspondant à la # partition donnée en paramètre def spectrogramme(self, partitions): @@ -324,11 +385,16 @@ class GenerateurExercice(GammeTemperee): result += "\draw[->, black] (0, " + str(self.frequenceEnCm(self.fmin)) + ") -- "; result += "(0," + str(self.hauteur) + ") node[above]{fréquence (Hz)};\n"; + + # lignes verticales + result += self.lignesVerticales() + # lignes horizontales + result += self.lignesHorizontales(partitions) # gradations sur les axes result += self.graduationAbscisses() result += self.graduationOrdonnees(partitions) - + couleur = { 0: "black", 1: "darkgray", 2: "gray"} for i,p in enumerate(partitions): result += self.notesSpectrogrammePartition(p, couleur.get(i, "lightgray")) diff --git a/musique/gamme.py b/musique/gamme.py index a9fa205b583cf22b44805cb6f168f57dbac86b39..068187627109602b215e14f33653659a0ee38438 100644 --- a/musique/gamme.py +++ b/musique/gamme.py @@ -115,8 +115,16 @@ class GammeTemperee: return result # retourne la liste des notes dans l'intervalle donné - def notesDansIntervalle(self, noteMin, noteMax): - return [ self.note(o, i) for (o, i) in self.getOctaveEtIDNoteDansIntervalle(noteMin, noteMax) ] + def notesDansIntervalle(self, noteMin, noteMax, uneSeuleParOctave = False): + if uneSeuleParOctave: + return [ self.note(o, i) for (o, i) in self.getOctaveEtIDNoteDansIntervalle(noteMin, noteMax) if i == 0 ] + else: + return [ self.note(o, i) for (o, i) in self.getOctaveEtIDNoteDansIntervalle(noteMin, noteMax) ] + + def notesDansPartition(self, partitions): + l = [[ x for x in [note[0] if isinstance(note[0], float) else note[0] for note in partition] if x != 0.] for partition in partitions] + return list(set([ j for i in l for j in i ])) + # retourne la fréquence minimum utilisée dans les partitions def minFrequence(self, partitions):