Skip to content
Snippets Groups Projects
Commit 8ad4b550 authored by Jean-Marie  FAVREAU's avatar Jean-Marie FAVREAU
Browse files

Beaucoup de corrections de bugs, on commence à avoir quelque chose de fonctionnel

parent e3720758
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,8 @@ SCRIPTS=$(wildcard *.py)
EXESPECTEX=$(addprefix $(EXERCICESDIR)/ex-spec-,$(SCRIPTS:.py=.tex))
EXESPECPDF=$(EXESPECTEX:.tex=.pdf)
WAVES=$(addprefix $(SONS)/,$(SCRIPTS:.py=.wav))
BOOMWHACKERS=boomwhackers-8.json
.PRECIOUS: $(EXESPECTEX)
all: waves pdf
......@@ -19,7 +21,7 @@ $(EXERCICESDIR)/%.pdf: $(EXERCICESDIR)/%.tex
cd $(EXERCICESDIR); pdflatex $(<:$(EXERCICESDIR)/%=%); cd ..
$(EXERCICESDIR)/ex-spec-%.tex: %.py
python $< --exercice-spectrogramme
python $< --exercice-spectrogramme --boomwhackers=$(BOOMWHACKERS)
$(SONS)/%.wav: %.py
python $<
......
......@@ -12,11 +12,15 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition de Bella Ciao.')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(100)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
bellaciao = [ [ [gamme.mi(4), gamme.croche],
[gamme.la(4), gamme.croche],
......@@ -74,6 +78,7 @@ bellaciao = [ [ [gamme.mi(4), gamme.croche],
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(bellaciao, "exercices/ex-spec-bellaciao.tex", "thème \"Bella Ciao\"")
else:
print "Génération de la version \"piano\""
......
......@@ -15,11 +15,15 @@ parser = argparse.ArgumentParser(description='Génère des documents à \
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(117)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
crescendo = [ [ [gamme.do(3), gamme.noire],
[gamme.re(3), gamme.noire],
......@@ -33,6 +37,7 @@ crescendo = [ [ [gamme.do(3), gamme.noire],
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(crescendo,
"exercices/ex-spec-crescendo.tex",
"Crescendo")
......
......@@ -12,12 +12,17 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition de la cucaracha.')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(160)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
cucaracha = [ [ [gamme.re(4), gamme.noire],
[gamme.re(4), gamme.noire],
[gamme.re(4), gamme.noire],
......@@ -57,6 +62,7 @@ cucaracha = [ [ [gamme.re(4), gamme.noire],
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(cucaracha, "exercices/ex-spec-cucaracha.tex", "thème \"la cucaracha\"")
else:
print "Génération de la version \"piano\""
......
......@@ -8,12 +8,16 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition de "la lettre à Élise".')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(95)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
elise = [
......@@ -696,6 +700,7 @@ elise = [
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(elise, "exercices/ex-spec-elise.tex", "La lettre à Élise")
else:
print "Génération de la version \"piano\""
......
......@@ -12,11 +12,15 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition du thème du flic de Beverly Hills.')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(117)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
flic = [ [ [gamme.fad(4), gamme.noire],
[gamme.la(4), gamme.crochepointee],
......@@ -45,6 +49,7 @@ flic = [ [ [gamme.fad(4), gamme.noire],
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(flic, "exercices/ex-spec-flic.tex", "thème \"le flic de Beverly Hills\"")
else:
print "Génération de la version \"piano\""
......
......@@ -10,12 +10,16 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition du thème du flic de Beverly Hills (v2).')
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('--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]
flic2 = [ [ [gamme.mi(4), gamme.croche],
[gamme.sol(4), gamme.doublecrochepointee],
......@@ -44,6 +48,7 @@ flic2 = [ [ [gamme.mi(4), gamme.croche],
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(flic2, "exercices/ex-spec-flic2.tex", "thème \"le flic de Beverly Hills\"")
else:
print "Génération du son"
......
......@@ -12,11 +12,15 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition de Frère Jacques.')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(160)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
frerejacques = [ [ [gamme.sol(4), gamme.noire],
[gamme.la(4), gamme.noire],
......@@ -62,6 +66,7 @@ frerejacques = [ [ [gamme.sol(4), gamme.noire],
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(frerejacques, "exercices/ex-spec-frerejacques.tex", "thème \"Frère Jacques\"")
else:
print "Génération de la version \"piano\""
......
......@@ -9,9 +9,14 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition du thème joyeux anniversaire.')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
gamme = GammeTemperee(117)
......@@ -45,6 +50,7 @@ happy = [ [ [gamme.do(4), gamme.crochepointee],
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(happy, "exercices/ex-spec-happybirthday.tex", "thème joyeux anniversaire")
else:
print "Génération du son"
......
......@@ -9,13 +9,16 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition de "la vie en rose".')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(160)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
lavieenrose = [ [ [gamme.do(2), gamme.noirepointee],
[gamme.si(1), gamme.croche],
......@@ -64,6 +67,7 @@ lavieenrose = [ [ [gamme.do(2), gamme.noirepointee],
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(lavieenrose, "exercices/ex-spec-lavieenrose.tex", "La vie en rose")
else:
print "Génération de la version \"piano\""
......
......@@ -22,6 +22,16 @@ class GenerateurExercice(GammeTemperee):
self.margeFrequence = 100
self.margeFrequenceLegende = 20
self.margeLegende = 2.0
self.boomwhackers = []
def setBoomwhackers(self, mw):
import json
with open(mw) as f:
bw = json.load(f)
self.boomwhackers = {}
for key, value in bw.iteritems():
self.boomwhackers[(int(key[-1]), self.getIDNoteDepuisNom(key[:-1]))] = value
# 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
......@@ -35,17 +45,11 @@ class GenerateurExercice(GammeTemperee):
def calculeDureePartitions(self, partitions):
return max([self.calculeDureePartition(p) for p in partitions])
# calcule les fréquences minimales et maximales des partitions
def calculeIntervalleFrequencesPartition(self, partition):
minf = min([ min([ f for f in note[0]]) if not isinstance(note[0], float) else note[0] for note in partition])
maxf = max([ max([ f for f in note[0]]) if not isinstance(note[0], float) else note[0] for note in partition])
return (minf, maxf)
# calcule les fréquences minimales et maximales des partitions
def calculeIntervalleFrequencesPartitions(self, partitions):
intervalles = [ self.calculeIntervalleFrequencesPartition(p) for p in partitions]
return ( min([i[0] for i in intervalles]), max([i[1] for i in intervalles]))
notes = self.notesDansPartition(partitions)
return (min(notes), max(notes))
# cette fonction calcule l'échelle qui sera utilisée pour le spectrogramme:
......@@ -190,6 +194,7 @@ class GenerateurExercice(GammeTemperee):
result += str(i + 1) + " & "
if solution:
if isinstance(note[0], float):
if note[0] > 0:
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"
......@@ -233,25 +238,36 @@ class GenerateurExercice(GammeTemperee):
result += "\\end{table}\n"
return result
# retourne la translation d'octave nécessaire pour jouer avec
# les boomwhackers, ou une valeur supérieure à 100 si la note
# n'est pas disponible
def getTranslationOctaveBoomwhackers(self, minNote):
octaveCible = min([ n[0] for n in self.boomwhackers if n[1] == minNote[1] ] + [10000])
return octaveCible - minNote[0]
def estJouable(self, note, shiftOctave):
nN = (note[0] + shiftOctave, note[1])
return nN in self.boomwhackers
def estDessinable(self, partitions):
if len(partitions) != 1:
print "La partition contient plusieurs mains."
return False
if self.contientNoteAlteree(partitions):
print "La partition contient une alterée."
return False
notes = [ self.getOctaveEtIDNote(p) for p in self.notesDansPartition(partitions) ]
minNote = min(notes)
maxNote = max(notes)
print notes
# si les notes sont dans une même gamme
# ou qu'elles sont sur deux gammes, avec le do dans la gamme suivante
return minNote[0] == maxNote[0] or (minNote[0] == maxNote[0] + 1 and maxNote[1] == 0)
shiftOctave = self.getTranslationOctaveBoomwhackers(minNote)
if shiftOctave > 100:
return False
for n in notes:
if not self.estJouable(n, shiftOctave):
return False
return True
def partitionGraphique(self, partitions):
result = ""
......@@ -260,8 +276,9 @@ class GenerateurExercice(GammeTemperee):
if self.estDessinable(partitions):
p = partitions[0]
# TODO
result += "On peut la dessiner."
print "on peut la dessiner"
# TODO
else:
result += "Cette partition n'est pas représentable sous forme de partition pour boomwhackers diatoniques."
......@@ -371,6 +388,7 @@ class GenerateurExercice(GammeTemperee):
def graduationOrdonnees(self, partitions):
frequences = self.notesDansPartition(partitions)
result = ""
for frequence in frequences:
......
......@@ -9,6 +9,9 @@ class GammeTemperee:
def __init__(self, bpm = 120):
self.frequences = [4186.01, 4434.92, 4698.64, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93, 6644.88, 7040.00, 7458.62, 7902.13]
self.nomsNotes = [ ["do"], ["dod", "reb"], ["re"], ["red", "mib"],
["mi"], ["fa"], ["fad", "solb"], ["sol"], ["sold", "lab"],
["la"], ["lad", "sib"], ["si"]]
self.setBPM(bpm)
# Definition de chacune des notes du clavier (leur frequence).
# Paramètre:
......@@ -70,6 +73,12 @@ class GammeTemperee:
def silence(self):
return 0.
def getIDNoteDepuisNom(self, nom):
for i, noms in enumerate(self.nomsNotes):
if nom in noms:
return i
return -1
# definition des pauses (un silence joue pendant une duree donnee)
def pause(self):
return [ self.silence(), self.ronde ]
......@@ -122,32 +131,17 @@ class GammeTemperee:
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 ]))
l = [[ [x] if isinstance(x, float) else x for x in [note[0] if not isinstance(note[0], float) else note[0] for note in partition]] for partition in partitions]
return [x for x in sum(sum(l, []), []) if x != 0]
def isNoteAlteree(self, frequence):
(o, i) = self.getOctaveEtIDNote(frequence)
return i in [ 1, 3, 6, 8, 10 ]
def contientNoteAlteree(self, partitions):
for partition in partitions:
for note in partition:
if isinstance(note[0], float):
if self.isNoteAlteree(note[0]):
return True
else:
for n in note:
if self.isNoteAlteree(n[0]):
return True
return False
# retourne la fréquence minimum utilisée dans les partitions
def minFrequence(self, 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])
return min(self.notesDansPartition(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])
return max(self.notesDansPartition(partitions))
def durees(self, partitions):
......
......@@ -9,12 +9,15 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition de "rainbow".')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(130)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
rainbow = [ [ [gamme.do(3), gamme.blanche],
[gamme.do(3), gamme.noire],
......@@ -44,6 +47,7 @@ gamme.pause(),
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(rainbow, "exercices/ex-spec-rainbow.tex", "Rainbow")
else:
print "Génération du son"
......
......@@ -9,12 +9,15 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition de Stairway.')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(117)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
stair = [ [
[gamme.la(2), gamme.croche],
......@@ -47,6 +50,7 @@ stair = [ [
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(stair, "exercices/ex-spec-stairway.tex", "Stairway")
else:
print "Génération du son"
......
......@@ -8,11 +8,14 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition du thème de star wars.')
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
gamme = GammeTemperee(150)
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
starwars = [
......@@ -56,6 +59,7 @@ starwars = [
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(starwars, "exercices/ex-spec-starwars.tex", "thème StarWars")
else:
print "Génération de la version \"piano\""
......
......@@ -11,9 +11,15 @@ from musique.gamme import GammeTemperee
parser = argparse.ArgumentParser(description='Génère des documents à partir de la partition "j\'ai du bon tabac".')
parser.add_argument('--full', help="Génère l'ensemble des sons pour illustrer la construction du synthétiseur", dest='full', action='store_true',default=False)
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('--boomwhackers', help="Génère un exercice plutôt que le fichier son", dest='boomwhackers', nargs=1)
args = parser.parse_args()
boomwhackers = ""
if not args.boomwhackers is None:
boomwhackers = args.boomwhackers[0]
gamme = GammeTemperee(160)
tabac = [ [ [gamme.sol(3), gamme.noire],
......@@ -75,6 +81,7 @@ if args.full:
if args.exerciceSpectrogramme:
g = GenerateurExercice(gamme.bpm)
g.setBoomwhackers(boomwhackers)
g.genererExerciceSpectrogramme(tabac, "exercices/ex-spec-tabac.tex", "j'ai du bon tabac")
else:
print "Génération de la version \"piano\""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment