From df68e7e510499af212aff0245f03fa1ca6f89f80 Mon Sep 17 00:00:00 2001
From: Jean-Marie Favreau <jm.trivial@gmail.com>
Date: Wed, 6 Feb 2019 12:53:31 +0100
Subject: [PATCH] =?UTF-8?q?ajout=20de=20nouvelles=20m=C3=A9lodies,=20et=20?=
 =?UTF-8?q?am=C3=A9lioration=20des=20rendus?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Makefile            |  12 +++-
 brahms.py           |   9 ++-
 joie.py             |   8 ++-
 lune.py             |  58 +++++++++++++++
 musique/exercice.py | 169 ++++++++++++++++++++++++++++++++++++--------
 tabac2.py           |  50 +++++++------
 6 files changed, 247 insertions(+), 59 deletions(-)
 create mode 100644 lune.py

diff --git a/Makefile b/Makefile
index 0065516..7c9ae6b 100644
--- a/Makefile
+++ b/Makefile
@@ -4,24 +4,30 @@ SONS=sons/
 SCRIPTS=$(wildcard *.py)
 EXESPECTEX=$(addprefix $(EXERCICESDIR)/ex-spec-,$(SCRIPTS:.py=.tex))
 EXESPECPDF=$(EXESPECTEX:.tex=.pdf)
+
+EXEPROJTEX=$(EXERCICESDIR)/ex-proj-joie.tex $(EXERCICESDIR)/ex-proj-brahms.tex $(EXERCICESDIR)/ex-proj-lune.tex  $(EXERCICESDIR)/ex-proj-tabac2.tex
+EXEPROJPDF=$(EXEPROJTEX:.tex=.pdf)
 WAVES=$(addprefix $(SONS)/,$(SCRIPTS:.py=.wav))
 BOOMWHACKERS=boomwhackers-8.json
 
-.PRECIOUS: $(EXESPECTEX)
+.PRECIOUS: $(EXESPECTEX) $(EXEPROJTEX)
 
 all: waves pdf
 
 waves: $(WAVES)
 
-pdf: $(EXESPECPDF)
+pdf: $(EXESPECPDF) $(EXEPROJPDF)
 
-tex: $(EXESPECTEX)
+tex: $(EXESPECTEX) $(EXEPROJTEX)
 
 $(EXERCICESDIR)/%.pdf: $(EXERCICESDIR)/%.tex
 	cd $(EXERCICESDIR); pdflatex $(<:$(EXERCICESDIR)/%=%); cd ..
 	
 $(EXERCICESDIR)/ex-spec-%.tex: %.py
 	python $< --exercice-spectrogramme --boomwhackers=$(BOOMWHACKERS)
+
+$(EXERCICESDIR)/ex-proj-%.tex: %.py
+	python $< --exercice-spectrogramme-transparent --boomwhackers=$(BOOMWHACKERS)
 	
 $(SONS)/%.wav: %.py
 	python $< 
diff --git a/brahms.py b/brahms.py
index 1e68521..6a0de06 100644
--- a/brahms.py
+++ b/brahms.py
@@ -9,6 +9,7 @@ from musique.gamme import GammeTemperee
 
 parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition du thème Lullaby, berceuse de Brahms.')
 parser.add_argument('--exercice-spectrogramme', help="Génère un exercice plutôt que le fichier son", dest='exerciceSpectrogramme', action='store_true',default=False)
+parser.add_argument('--exercice-spectrogramme-transparent', help="Génère un exercice à projeter", dest='transparent', action='store_true',default=False)
 parser.add_argument('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
 
 args = parser.parse_args()
@@ -55,11 +56,15 @@ brahms = [ [ [gamme.mi(3), gamme.croche],
         ] ]
 
 
-if args.exerciceSpectrogramme:
+if args.exerciceSpectrogramme or args.transparent:
   g = GenerateurExercice(gamme.bpm)
   g.setBoomwhackers(boomwhackers)
   g.setLongueurPartitionColoree(6)
-  g.genererExerciceSpectrogramme(brahms, "exercices/ex-spec-brahms.tex", "thème 2")
+  if args.exerciceSpectrogramme:
+    g.genererExerciceSpectrogramme(brahms, "exercices/ex-spec-brahms.tex", "thème 4", "Lullaby, berceuse de Brahms")
+  if args.transparent:
+    g.genererTransparentSpectrogramme(brahms, "exercices/ex-proj-brahms.tex", "thème 4", "Lullaby, berceuse de Brahms")
+  
 else:
   print "Génération du son"
   s = BasicSequenceur(1, gamme.bpm, 0)
diff --git a/joie.py b/joie.py
index 4c1765c..6119346 100644
--- a/joie.py
+++ b/joie.py
@@ -9,6 +9,7 @@ from musique.gamme import GammeTemperee
 
 parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition du thème ode à la joie.')
 parser.add_argument('--exercice-spectrogramme', help="Génère un exercice plutôt que le fichier son", dest='exerciceSpectrogramme', action='store_true',default=False)
+parser.add_argument('--exercice-spectrogramme-transparent', help="Génère un exercice à projeter", dest='transparent', action='store_true',default=False)
 parser.add_argument('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
 
 args = parser.parse_args()
@@ -67,11 +68,14 @@ joie = [ [ [E, gamme.noire],
         ] ]
 
 
-if args.exerciceSpectrogramme:
+if args.exerciceSpectrogramme or args.transparent:
   g = GenerateurExercice(gamme.bpm)
   g.setBoomwhackers(boomwhackers)
   g.setLongueurPartitionColoree(8)
-  g.genererExerciceSpectrogramme(joie, "exercices/ex-spec-joie.tex", "thème 1")
+  if args.exerciceSpectrogramme:
+    g.genererExerciceSpectrogramme(joie, "exercices/ex-spec-joie.tex", "thème 1", "Hymne à la joie")
+  if args.transparent:
+    g.genererTransparentSpectrogramme(joie, "exercices/ex-proj-joie.tex", "thème 1", "Hymne à la joie")
 else:
   print "Génération du son"
   s = BasicSequenceur(1, gamme.bpm, 0)
diff --git a/lune.py b/lune.py
new file mode 100644
index 0000000..efd0dd3
--- /dev/null
+++ b/lune.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# coding: utf8
+# -*- coding: utf-8 -*-
+
+import argparse
+from musique.basicsynth import BasicSequenceur
+from musique.exercice import GenerateurExercice
+from musique.gamme import GammeTemperee
+
+parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition du thème au clair de la lune.')
+parser.add_argument('--exercice-spectrogramme', help="Génère un exercice plutôt que le fichier son", dest='exerciceSpectrogramme', action='store_true',default=False)
+parser.add_argument('--exercice-spectrogramme-transparent', help="Génère un exercice à projeter", dest='transparent', action='store_true',default=False)
+parser.add_argument('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
+
+args = parser.parse_args()
+
+gamme = GammeTemperee(80)
+
+
+boomwhackers = ""
+if not args.boomwhackers is None:
+  boomwhackers = args.boomwhackers[0]
+
+
+lune = [ [ [gamme.do(4), gamme.croche],
+           [gamme.do(4), gamme.croche],
+           [gamme.do(4), gamme.croche],
+           [gamme.re(4), gamme.croche],
+           
+           [gamme.mi(4), gamme.noire],
+           [gamme.re(4), gamme.noire],
+           
+           [gamme.do(4), gamme.croche],
+           [gamme.mi(4), gamme.croche],
+           [gamme.re(4), gamme.croche],
+           [gamme.re(4), gamme.croche],
+           
+           [gamme.do(4), gamme.blanche],
+           
+           
+           
+        ] ]
+
+
+if args.exerciceSpectrogramme or args.transparent:
+  g = GenerateurExercice(gamme.bpm)
+  g.setBoomwhackers(boomwhackers)
+  g.setLongueurPartitionColoree(4)
+  if args.exerciceSpectrogramme:
+    g.genererExerciceSpectrogramme(lune, "exercices/ex-spec-lune.tex", "thème 2", "Au clair de la lune")
+  if args.transparent:
+    g.genererTransparentSpectrogramme(lune, "exercices/ex-proj-lune.tex", "thème 2", "Au clair de la lune")
+    
+else:
+  print "Génération du son"
+  s = BasicSequenceur(1, gamme.bpm, 0)
+  s.genererMelodie(lune, "sons/lune.wav")
+
diff --git a/musique/exercice.py b/musique/exercice.py
index 41904ed..4fe2bb5 100644
--- a/musique/exercice.py
+++ b/musique/exercice.py
@@ -106,11 +106,41 @@ class GenerateurExercice(GammeTemperee):
         result += "\\maketitle\n"
         result += "\\thispagestyle{empty}\n"
         return result
-    
+
+    def enteteBeamer(self, titre):
+        result = "\\documentclass{beamer}\n"
+        result += "\\usepackage[utf8]{inputenc}\n"
+        result += "\\usepackage[french]{babel}\n"
+        result += "\\usepackage{tikz,pgfplots}\n"
+        result += "\\usepackage{float}\n"
+        result += "\\usetikzlibrary{positioning}\n"
+        result += "\\usetikzlibrary{shapes.geometric}\n"
+        result += "\\usetikzlibrary{shapes.symbols}\n"
+        result += "\\usetikzlibrary{shadows}\n"
+        result += "\\usetikzlibrary{decorations.pathmorphing, patterns,shapes}\n"
+        result += "\\usetikzlibrary{positioning, decorations.markings}\n"
+        result += "\\usepgflibrary{arrows}\n"
+        result += "\\usetikzlibrary{arrows}\n"
+        result += "\\pagestyle{empty}\n"
+        result += "\\usepackage{helvet}"
+        result += "\\usepackage{musixtex}"
+        result += "\\usepackage{harmony}"
+        result += "\\renewcommand{\\familydefault}{\\sfdefault}"
+
+
+        result += "\\title{" + titre + "}\n"
+        result += "\\date{}\n"
+        result += "\\begin{document}\n"
+        result += "\\frame{\\titlepage}"
+        return result
+
     # cette fonction retourne le pied d'un document LaTeX
     def piedLaTeX(self):
         return "\\end{document}\n"
 
+    # cette fonction retourne le pied d'un document Beamer
+    def piedBeamer(self):
+        return "\\end{document}\n"
     # cette fonction écrit le début de l'exercice spectrogramme
     def debutExerciceSpectrogramme(self):
         result = "\n"
@@ -185,7 +215,7 @@ class GenerateurExercice(GammeTemperee):
         # on ne va utiliser que la première partition
         partition = partitions[0]
         
-        result = "\\renewcommand{\\arraystretch}{1.5}"
+        result = "\\renewcommand{\\arraystretch}{1.3}"
         result += "\\begin{table}[H]\n\centering\n"
         if solution:
           result += "\\begin{tabular}{|c||c|c||c|c|}\n"
@@ -217,7 +247,7 @@ class GenerateurExercice(GammeTemperee):
           else:
             result +=  " &  \\\\\n"
             result += "\\hline\n"
-        if not solution:
+        if solution:
           result += "\\hline\n"
         result += "\\end{tabular}\n"
         if solution:
@@ -305,19 +335,27 @@ class GenerateurExercice(GammeTemperee):
       
       return result
     
-    def ensembleDesNotesGraphiques(self, frequences, radius):
+    def ensembleDesNotesGraphiques(self, frequences, radius, beamer):
       result = ""
       
       notes = sorted(list(set(frequences)))
       
       result += "\\begin{table}[H]\n\centering\n"
-      result += "\\begin{tabular}{|r|" + "".join(["c|"] * len(notes)) +  "}\n"
-      result += "\\hline\n"
+      if not beamer:
+        result += "\\begin{tabular}{|r|" + "".join(["c|"] * len(notes)) +  "}\n"
+      else:
+        result += "\\begin{tabular}{r|" + "".join(["c"] * len(notes)) +  "}\n"
+      if not beamer:
+        result += "\\hline\n"
       
       result += "Notes"
       for n in notes:
         result += "&"
+        if beamer:
+          result += "\\hspace*{.2cm}"
         result += self.frequenceToLaTeX(n)
+        if beamer:
+          result += "\\hspace*{.2cm}"
       result += "\\\\ \n"
       result += "Forme"
       for n in notes:
@@ -328,27 +366,40 @@ class GenerateurExercice(GammeTemperee):
         result += self.pointColore(mw, 0, 0, radius)
         result += "\\end{tikzpicture}"
       result += "\\\\ \n"
-      result += "Prénom"
-      for n in notes:
-        result += "&"
-        result += "\\hspace*{2cm}"
-      result += "\\\\ \n"
-      result += "\\hline\n"
+      if not beamer:
+        result += "Prénom"
+        for n in notes:
+          result += "&"
+          result += "\\hspace*{2cm}"
+        result += "\\\\ \n"
+      if not beamer:
+        result += "\\hline\n"
       result += "\\end{tabular}\n"
       result += "\\caption{Représentation colorée des notes}\n"
       result += "\\end{table}\n"
       return result
     
-    def partitionGraphique(self, partitions):
+    def partitionGraphique(self, partitions, beamer = False):
+
+
       result = ""
       
+      if beamer:
+          result += "\\frame{"
+          result += "\\frametitle{Partition graphique}"
+      
       frequences = self.notesDansPartition(partitions)
       
       x = 0.
       y = 0.
       
-      stepx = 2
-      stepy = 2.5
+      if beamer:
+        stepx = 1
+        stepy = 1.2
+      else:
+        stepx = 2
+        stepy = 2.5
+
       radius = stepx * 0.22
       
       finDeLigne = self.longueurPartitionColoree * stepx
@@ -358,9 +409,10 @@ class GenerateurExercice(GammeTemperee):
         p = partitions[0]
 
         
-        result += self.ensembleDesNotesGraphiques(frequences, radius)
+        result += self.ensembleDesNotesGraphiques(frequences, radius, beamer)
 
-        result += "La partition graphique suivante se lit ligne par ligne. Les durées sont représentées par les espaces entre les cercles colorés. \n \n"
+        if not beamer:
+          result += "La partition graphique suivante se lit ligne par ligne. Les durées sont représentées par les espaces entre les cercles colorés. \n \n"
 
         result += "\\begin{figure}[H]"
         result += "\\begin{tikzpicture}[]"
@@ -384,15 +436,23 @@ class GenerateurExercice(GammeTemperee):
               
         
         result += "\\end{tikzpicture}"
-        result += "\\caption{Partition graphique retranscrite depuis le tableau des notes de la partition}"
+        if not beamer:
+          result += "\\caption{Partition graphique retranscrite depuis le tableau des notes de la partition}"
         result += "\\end{figure}"
       else:
         result += "Cette partition n'est pas représentable sous forme de partition pour boomwhackers diatoniques."
-            
+      
+      if beamer:
+        result += "}"
       return result
 
-    def partitionMusicale(self, partitions):
+    def partitionMusicale(self, partitions, beamer = False):
       result = ""
+      
+      if beamer:
+          result += "\\frame{"
+          result += "\\frametitle{Partition musicale}"
+
       if len(partitions) == 1:
         partition = partitions[0]
         
@@ -407,7 +467,10 @@ class GenerateurExercice(GammeTemperee):
         maxNote = max([ n for n in notes if n[1] > 0])
         (maxoctave, maxidnote) = maxNote
         midOctave = int((maxoctave + minoctave) / 2)
-        result += "\\normalmusicsize"
+        if beamer:
+          result += "\\normalmusicsize"
+        else:
+          result += "\\Largemusicsize"
         result += "\\begin{figure}[H]"
         result += "\\begin{music}"
         #result += "\\parindent10mm"
@@ -427,15 +490,16 @@ class GenerateurExercice(GammeTemperee):
         result += "\\end{music}"
         result += "\\caption{Partition simplifiée}"
         result += "\\end{figure}"
-
       else:
         result += "Le générateur d'exercice ne prend pas en charge cette partition."
-        
+      
+      if beamer:
+        result += "}"
       return result
 
 
     # cette fonction écrit la fin de l'exercice spectrogramme
-    def finExerciceSpectrogramme(self, partitions):
+    def finExerciceSpectrogramme(self, partitions, nomSolution):
         result = "\n"
 
         result += "~\\clearpage\n"
@@ -457,16 +521,23 @@ class GenerateurExercice(GammeTemperee):
         result += self.tableauNotesBrutes(partitions, False)
 
 
+        result += "~\\clearpage\n"
         result += "\\section{Solution}\n"
         # on écrit le tableau solution de l'exercice
         result += self.tableauNotesBrutes(partitions, True)
 
+        result += "~\\clearpage\n"
+        
         result += "\\section{Partition graphique}\n"
         result += self.partitionGraphique(partitions)
 
         result += "\\section{Partition musicale}\n"
         result += self.partitionMusicale(partitions)
 
+        if nomSolution != "":
+          result += "\\section{Solution}\n"
+          result += "Cette mélodie s'appelle " + nomSolution
+
 
         return result
     
@@ -598,11 +669,19 @@ class GenerateurExercice(GammeTemperee):
     
     # cette fonction écrit le spectrogramme simplifié correspondant à la 
     # partition donnée en paramètre
-    def spectrogramme(self, partitions):
-        # on commence par initialiser l'échelle
-        self.initialisationEchelleSpectrogramme(partitions, 21 - 2 * self.margeDocument - self.margeLegende, 12)
+    def spectrogramme(self, partitions, beamer = False):
         result = ""
 
+        # on commence par initialiser l'échelle
+        if beamer:
+          result += "\\frame{"
+          result += "\\frametitle{Spectrogramme}"
+          self.initialisationEchelleSpectrogramme(partitions, 12 - 2 * self.margeDocument - self.margeLegende, 7)
+        else:
+          self.initialisationEchelleSpectrogramme(partitions, 21 - 2 * self.margeDocument - self.margeLegende, 12)
+          
+          
+
         result += "\\begin{tikzpicture}[]"
         
         # lignes verticales
@@ -631,6 +710,9 @@ class GenerateurExercice(GammeTemperee):
           result += self.notesSpectrogrammePartition(p, couleur.get(i, "lightgray"))
 
         result += "\\end{tikzpicture}"
+        
+        if beamer:
+          result += "}"
         return result
 
   
@@ -642,7 +724,7 @@ class GenerateurExercice(GammeTemperee):
     #   où chaque liste décrit la partition d'une "main". Une partition est décrite comme 
     #   une liste d'éléments composés d'une ou plusieurs notes (quantifiée par une frequence) et d'une duree exprimee en seconde.
     # * nomFichier: le nom d'un fichier où sera sauvée la feuille d'exercice
-    def genererExerciceSpectrogramme(self, partitions, nomFichier, nomMelodie):
+    def genererExerciceSpectrogramme(self, partitions, nomFichier, nomMelodie, nomSolution=""):
        
         # on ouvre le fichier
         l_fichier = open(nomFichier, "w")
@@ -657,10 +739,39 @@ class GenerateurExercice(GammeTemperee):
         l_fichier.write(self.spectrogramme(partitions))
         
         # on écrit la suite de l'exercice
-        l_fichier.write(self.finExerciceSpectrogramme(partitions))
+        l_fichier.write(self.finExerciceSpectrogramme(partitions, nomSolution))
         
         # on écrit la fin du document LaTeX
         l_fichier.write(self.piedLaTeX())
         
         # on ferme le fichier
         l_fichier.close()
+        
+    def genererTransparentSpectrogramme(self, partitions, nomFichier, nomMelodie, nomSolution=""):
+        
+        # on ouvre le fichier
+        l_fichier = open(nomFichier, "w")
+        
+        # on écrit les entêtes du document LaTeX
+        l_fichier.write(self.enteteBeamer(nomMelodie))
+        
+        l_fichier.write(self.spectrogramme(partitions, True))
+        
+        l_fichier.write(self.partitionGraphique(partitions, True))
+
+        l_fichier.write(self.partitionMusicale(partitions, True))
+
+        if nomSolution != "":
+          result = "\\frame{"
+          result += "\\frametitle{Solution}\n"
+          result += "\\begin{center}\Large Cette mélodie s'appelle " + nomSolution + "\\end{center}"
+          result += "}"
+          l_fichier.write(result)
+
+
+        
+        # on écrit la fin du document LaTeX
+        l_fichier.write(self.piedBeamer())
+        
+        # on ferme le fichier
+        l_fichier.close()        
diff --git a/tabac2.py b/tabac2.py
index fbdd7aa..011d874 100644
--- a/tabac2.py
+++ b/tabac2.py
@@ -9,6 +9,7 @@ from musique.gamme import GammeTemperee
 
 parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition du thème j\'ai du bon tabac.')
 parser.add_argument('--exercice-spectrogramme', help="Génère un exercice plutôt que le fichier son", dest='exerciceSpectrogramme', action='store_true',default=False)
+parser.add_argument('--exercice-spectrogramme-transparent', help="Génère un exercice à projeter", dest='transparent', action='store_true',default=False)
 parser.add_argument('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
 
 args = parser.parse_args()
@@ -21,42 +22,45 @@ if not args.boomwhackers is None:
   boomwhackers = args.boomwhackers[0]
 
 
-tabac = [ [ [gamme.fa(3), gamme.croche],
-            [gamme.sol(3), gamme.croche],
-            [gamme.la(3), gamme.croche],
-            [gamme.fa(3), gamme.croche],
+tabac = [ [ [gamme.do(3), gamme.croche],
+            [gamme.re(3), gamme.croche],
+            [gamme.mi(3), gamme.croche],
+            [gamme.do(3), gamme.croche],
             
-            [gamme.sol(3), gamme.noire],
-            [gamme.sol(3), gamme.croche],
-            [gamme.la(3), gamme.croche],
+            [gamme.re(3), gamme.noire],
+            [gamme.re(3), gamme.croche],
+            [gamme.mi(3), gamme.croche],
              
-            [gamme.sib(3), gamme.noire],
-            [gamme.sib(3), gamme.noire],
+            [gamme.fa(3), gamme.noire],
+            [gamme.fa(3), gamme.noire],
             
-            [gamme.la(3), gamme.noire],
-            [gamme.la(3), gamme.noire],
+            [gamme.mi(3), gamme.noire],
+            [gamme.mi(3), gamme.noire],
             
-            [gamme.fa(3), gamme.croche],
-            [gamme.sol(3), gamme.croche],
-            [gamme.la(3), gamme.croche],
-            [gamme.fa(3), gamme.croche],
+            [gamme.do(3), gamme.croche],
+            [gamme.re(3), gamme.croche],
+            [gamme.mi(3), gamme.croche],
+            [gamme.do(3), gamme.croche],
             
-            [gamme.sol(3), gamme.noire],
-            [gamme.sol(3), gamme.croche],
-            [gamme.la(3), gamme.croche],
+            [gamme.re(3), gamme.noire],
+            [gamme.re(3), gamme.croche],
+            [gamme.mi(3), gamme.croche],
             
-            [gamme.sib(3), gamme.noire],
-            [gamme.do(4), gamme.noire],
+            [gamme.fa(3), gamme.noire],
+            [gamme.sol(3), gamme.noire],
             
-            [gamme.fa(3), gamme.blanche]
+            [gamme.do(3), gamme.blanche]
         ] ]
 
 
-if args.exerciceSpectrogramme:
+if args.exerciceSpectrogramme or args.transparent:
   g = GenerateurExercice(gamme.bpm)
   g.setBoomwhackers(boomwhackers)
   g.setLongueurPartitionColoree(6)
-  g.genererExerciceSpectrogramme(tabac, "exercices/ex-spec-tabac2.tex", "thème 2")
+  if args.exerciceSpectrogramme:
+    g.genererExerciceSpectrogramme(tabac, "exercices/ex-spec-tabac2.tex", "thème 3", "j'ai du bon tabac")
+  if args.transparent:
+    g.genererTransparentSpectrogramme(tabac, "exercices/ex-proj-tabac2.tex", "thème 3", "j'ai du bon tabac")
 else:
   print "Génération du son"
   s = BasicSequenceur(1, gamme.bpm, 0)
-- 
GitLab