Skip to content
Snippets Groups Projects
Commit 04a26b1f authored by Jean-Marie Favreau's avatar Jean-Marie Favreau
Browse files

Fin exercices

parent c076d489
Branches
No related tags found
No related merge requests found
......@@ -16,9 +16,9 @@ class GenerateurExercice(GammeTemperee):
GammeTemperee.__init__(self, bpm)
self.dureeFrappe = dureeFrappe
self.margeDocument = 1.0
self.margeDuree = 0.1
self.margeFrequence = 10
self.margeLegende = 1.0
self.margeDuree = 0.5
self.margeFrequence = 25
self.margeLegende = 2.0
# calcule la durée de la partition donnée en paramètre, dans le
# cas où elle est jouée au battement par minute courant
......@@ -61,7 +61,6 @@ class GenerateurExercice(GammeTemperee):
self.echelleX = largeur / (self.duree + self.margeDuree * 2)
self.echelleY = hauteur / (self.fmax - self.fmin + self.margeFrequence * 2)
print self.echelleX, self.echelleY
# cette fonction retourne l'entête d'un document LaTeX
......@@ -70,6 +69,7 @@ class GenerateurExercice(GammeTemperee):
result += "\\usepackage[utf8]{inputenc}\n"
result += "\\usepackage[french]{babel}\n"
result += "\\usepackage{tikz,pgfplots}\n"
result += "\\usepackage{float}\n"
result += "\\usepackage[margin=" + str(self.margeDocument) + "cm]{geometry}\n"
result += "\\usetikzlibrary{positioning}\n"
result += "\\usetikzlibrary{shapes.geometric}\n"
......@@ -93,18 +93,18 @@ class GenerateurExercice(GammeTemperee):
# cette fonction écrit le début de l'exercice spectrogramme
def debutExerciceSpectrogramme(self):
result = "\n"
result += "\\section{Les fréquences de la gamme tempérée}\n"
result += "La fréquence associée à chacune des notes notées sur une partition a varié au fil du temps. La conférence internationale de Londres de 1953 a fixé à 440~Hz la fréquence du $la^3$, ou \emph{$la$ du diapason}. Le système d'accord le plus répandu aujourd'hui est la gamme tempérée, qui divise l'octave en 12 intervalles chromatiques égaux, en s'éloignant légèrement des intonations justes afin de simplifier la gamme tout en permettant les accords conçus aux siècles précédents. Le tableau ci-dessous donne les fréquences pour chacune des notes de l'octave contenant le $la$ du diapason.\n"
result += "\\begin{center}\n"
result += "{\\scriptsize \\begin{tabular}{r|ccccccccccccc}\n"
result += "note & \\textbf{do} & do$\\sharp$ & ré & mi$\\flat$ & mi & fa & fa$\\sharp$ &sol & sol$\\sharp$ & la & si$\\flat$ & si & \\textbf{do} \\\\\n"
result += "\\hline\n"
result += " Fréquence & 264,00 & 279,70& 296,33 & 313,95& 332,62& 352,40& 373,35& 395,55& 419,07& 443,99& 470,39& 498,37& 528,00 \\\\\n"
result += "\\end{tabular}}\n"
result += "\\end{center}\n"
result += "\n"
result += "\n"
result += "\n"
#result += "\\section{Les fréquences de la gamme tempérée}\n"
#result += "La fréquence associée à chacune des notes notées sur une partition a varié au fil du temps. La conférence internationale de Londres de 1953 a fixé à 440~Hz la fréquence du $la^3$, ou \emph{$la$ du diapason}. Le système d'accord le plus répandu aujourd'hui est la gamme tempérée, qui divise l'octave en 12 intervalles chromatiques égaux, en s'éloignant légèrement des intonations justes afin de simplifier la gamme tout en permettant les accords conçus aux siècles précédents. Le tableau ci-dessous donne les fréquences pour chacune des notes de l'octave contenant le $la$ du diapason.\n"
#result += "\\begin{center}\n"
#result += "{\\scriptsize \\begin{tabular}{r|ccccccccccccc}\n"
#result += "note & \\textbf{do} & do$\\sharp$ & ré & mi$\\flat$ & mi & fa & fa$\\sharp$ &sol & sol$\\sharp$ & la & si$\\flat$ & si & \\textbf{do} \\\\\n"
#result += "\\hline\n"
#result += " Fréquence & 264,00 & 279,70& 296,33 & 313,95& 332,62& 352,40& 373,35& 395,55& 419,07& 443,99& 470,39& 498,37& 528,00 \\\\\n"
#result += "\\end{tabular}}\n"
#result += "\\end{center}\n"
#result += "\n"
#result += "\n"
#result += "\n"
result += "\n"
result += "\\section{Analyse de spectrogramme}\n"
# TODO
......@@ -114,35 +114,96 @@ class GenerateurExercice(GammeTemperee):
# retourne un tableau des durées des notes possibles dans la partition
def tableauDurees(self, partitions):
result = ""
# TODO
result = "\n"
result += "Cette partition est proposée à une fréquence de " + str(self.bpm) + " noires par minute, ce qui donne les durées suivantes."
ds = self.durees(partitions)
result += "\\begin{table}[H]\n\centering\n"
result += "\\begin{tabular}{c|c}\n"
result += "\\textbf{Tête de note} & \\textbf{Durée} (s) \\\\ \n"
result += "\\hline \n"
for duree in ds:
result += self.nomDuree(duree) + " & " + '{0:.2f}'.format(duree) + " \\\\\n"
result += "\\end{tabular}\n"
result += "\\caption{Table des durées}\n"
result += "\\end{table}\n"
return result
# retourne un tableau LaTeX décrivant la partition sous forme brute (fréquence
# et durée de chacune des notes)
def tableauNotesBrutes(self, partitions, solution):
def tableauNotesBrutes(self, partitions, solution = False):
# on ne va utiliser que la première partition
partition = partitions[0]
result = ""
result += "\\begin{tabular}{c|cc}\n"
result += "\\textbf{Note} & ... TODO"
result += "\\begin{table}[H]\n\centering\n"
result += "\\begin{tabular}{c||c|c||c|c}\n"
result += " & \multicolumn{2}{c||}{Lecture} & \multicolumn{2}{c}{Transcription} \\\\ \n"
result += "\\textbf{Note} & \\textbf{Fréquence} (Hz) & \\textbf{Durée} (s) & \\textbf{Note} & \\textbf{Durée} \\\\ \n"
result += "\\hline \n"
for i, note in enumerate(partition):
result += str(i) + " & " + '{0:.2f}'.format(note[0]) + " & " + '{0:.2f}'.format(note[1]) + "\\\\\n"
result += str(i) + " & "
if solution:
if isinstance(note[0], float):
result += '{0:.2f}'.format(note[0]) + " & " + '{0:.2f}'.format(note[1]) + " & "
result += self.frequenceToLaTeX(note[0]) + "& " + self.nomDuree(note[1]) + " \\\\\n"
else:
result += ', '.join(['{0:.2f}'.format(n) for n in note[0]]) + " & " + '{0:.2f}'.format(note[1])
result += " & " + ', '.join([self.frequenceToLaTeX(n) for n in note[0]]) + " & " + self.nomDuree(note[1]) + " \\\\\n"
else:
result += " & & & \\\\\n"
result += "\\end{tabular}\n"
# TODO
if solution:
result += "\\caption{Tableau des notes de la partition (solution)}\n"
else:
result += "\\caption{Tableau des notes de la partition}\n"
result += "\\end{table}\n"
return result
def tableauFrequences(self, partitions):
result = ""
notes = self.getOctaveEtIDNoteDansIntervalle(self.minFrequence(partitions), self.maxFrequence(partitions))
result += "Fréquences de chacune des notes utilisées sur la partition:"
result += "\\begin{table}[H]\n\centering\n"
result += "\\begin{tabular}{c|c}\n"
result += "\\textbf{Note} & \\textbf{Fréquence} (Hz) \\\\ \n"
result += "\\hline \n"
for note in notes:
result += self.toLaTeX(note[0], note[1]) + " & " + '{0:.2f}'.format(self.note(note[0], note[1])) + "\\\\\n"
result += "\\end{tabular}\n"
result += "\\caption{Table des fréquences de la gamme tempérée}\n"
result += "\\end{table}\n"
return result
# cette fonction écrit la fin de l'exercice spectrogramme
def finExerciceSpectrogramme(self, partitions):
result = "\n"
# on écrit le tableau de l'exercice à remplir
result += "Remplir le tableau par lecture graphique: "
result += self.tableauNotesBrutes(partitions, False)
# on écrit le tableau de durées
result += self.tableauDurees(partitions)
# on écrit le tableau de l'exercice à remplir
result += self.tableauNotesBrutes(partitions, False)
# on écrit le tableau des fréquences
result += self.tableauFrequences(partitions)
result += "\\section{Solution}\n"
# on écrit le tableau solution de l'exercice
result += self.tableauNotesBrutes(partitions, True)
......@@ -185,9 +246,24 @@ class GenerateurExercice(GammeTemperee):
# cette classe dessine les gradations sur les axes des abscisses
def graduationAbscisses(self):
nbGraduations = self.duree
# TODO
return ""
nbGraduations = int(self.duree)
pas = 1.
while nbGraduations > 10:
pas *= 2.
nbGraduations = int(self.duree / pas)
while nbGraduations < 4:
pas /= 2.
nbGraduations = int(self.duree / pas)
result = ""
for i in range(0, nbGraduations + 1):
h = i * pas
hinc = self.horodatageEnCm(h)
result += "\draw[black] (" + str(hinc) + ", -0.1) -- ";
result += "(" + str(hinc) + ", 0.)\n";
result += "(" + str(hinc) + ", -0.1) node[below]{" + '{0:.2f}'.format(h).replace(".", ",") + "};\n";
return result
def graduationOrdonnees(self, partitions):
frequences = self.notesDansIntervalle(self.minFrequence(partitions), self.maxFrequence(partitions))
......@@ -213,14 +289,14 @@ class GenerateurExercice(GammeTemperee):
# axe des abscisses
result += "\draw[->, black] (0, 0) -- ";
result += "(" + str(self.largeur) + ", 0) node[below]{durée};\n";
result += "(" + str(self.largeur) + ", 0) node[below]{durée (s)};\n";
# axe des ordonnées
result += "\draw[black, dashed] (0, 0) -- ";
result += "(0," + str(self.frequenceEnCm(self.fmin)) + ");\n";
result += "\draw[->, black] (0, " + str(self.frequenceEnCm(self.fmin)) + ") -- ";
result += "(0," + str(self.hauteur) + ") node[rotate=90, left, anchor=south]{fréquence};\n";
result += "(0," + str(self.hauteur) + ") node[rotate=90, left, anchor=south]{fréquence (Hz)};\n";
# gradations sur les axes
result += self.graduationAbscisses()
......
......@@ -61,10 +61,10 @@ class GammeTemperee:
# converti une note en son écriture en LaTeX
def toLaTeX(self, octave, idNote):
notes = [ "do", "do$\\sharp$ / ré$\\flat$", "", "ré$\\sharp$ / mi$\\flat$",
"mi", "fa", "fa$\\sharp$ / sol$\\flat$", "sol", "sol$\\sharp$ / la$\\flat$",
"la", "la$\\sharp$ / si$\\flat$", "si"]
return notes[idNote] + "^" + str(octave)
notes = [ ["do"], ["do$\\sharp$", "ré$\\flat$"], [""], ["ré$\\sharp$", "mi$\\flat$"],
["mi"], ["fa"], ["fa$\\sharp$", "sol$\\flat$"], ["sol"], ["sol$\\sharp$", "la$\\flat$"],
["la"], ["la$\\sharp$", "si$\\flat$"], ["si"]]
return ", ".join([n + "$^" + str(octave) + "$" for n in notes[idNote]])
# definition de la frequence du silence
def silence(self):
......@@ -93,9 +93,15 @@ class GammeTemperee:
print("erreur, note inconnue: " + str(note))
return (-1, -1)
# converti une note donnée en fréquence en son écriture LaTeX
def frequenceToLaTeX(self, frequence):
(o, i) = self.getOctaveEtIDNote(frequence)
return self.toLaTeX(o, i)
# retourne l'octave et l'identifiant de la note pour chacune des notes de l'intervalle donné en fréquence
def getOctaveEtIDNoteDansIntervalle(self, noteMin, noteMax):
if noteMin > noteMax:
return self.notesDansIntervalle(noteMax, noteMin)
return self.getOctaveEtIDNoteDansIntervalle(noteMax, noteMin)
(octaveMin, idNoteMin) = self.getOctaveEtIDNote(noteMin)
(octaveMax, idNoteMax) = self.getOctaveEtIDNote(noteMax)
......@@ -112,12 +118,21 @@ class GammeTemperee:
def notesDansIntervalle(self, noteMin, noteMax):
return [ self.note(o, i) for (o, i) in self.getOctaveEtIDNoteDansIntervalle(noteMin, noteMax) ]
# retourne la fréquence minimum utilisée dans les partitions
def minFrequence(self, partitions):
return min([min([note[0] if isinstance(note[0], float) else min(note[0]) for note in partition]) for partition in partitions])
return min([min([ x for x in [note[0] if isinstance(note[0], float) else min(note[0]) for note in partition] if x != 0.]) for partition in partitions])
# retourne la fréquence maximum utilisée dans les partitions
def maxFrequence(self, partitions):
return max([max([note[0] if isinstance(note[0], float) else max(note[0]) for note in partition]) for partition in partitions])
def durees(self, partitions):
d = set()
for partition in partitions:
for n in partition:
d.add(n[1])
return sorted(list(d))
# Etant donne un nombre de battements par minute, cette fonction fixe la duree
# de chacune des notes, exprimée en secondes
# Paramètre:
......@@ -141,6 +156,18 @@ class GammeTemperee:
self.rondepointee = self.ronde * 1.5
self.carreepointee = self.carree * 1.5
def nomDuree(self, duree):
noms = { self.noire: "noire", self.croche: "croche", self.doublecroche: "double croche",
self.triplecroche: "triple croche", self.blanche: "blanche", self.ronde: "ronde",
self.carree: "carrée", self.noirepointee: "noire pointée", self.crochepointee: "croche pointée",
self.doublecrochepointee: "double croche pointée", self.blanchepointee: "blanche pointée",
self.rondepointee: "ronde pointée", self.carreepointee: "carrée pointée" }
if duree in noms:
return noms[duree]
else:
return "inconnue"
# d'après wikipédia, «le triolet est une division exceptionnelle du temps, formée d'un
#groupe de trois figures égales dont la somme équivaut à deux figures identiques dans un
# temps normalement binaire. »
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment