# Un générateur de code rythmique # Prend en entrée un sortie verbeuse du frontal de compilation du rythme # Fournit en sortie un fichier de commandes (echo ^G; sleep) # Le 18 septembre 2004 par Gilles DRIDI # Modifié le 1 janvier 2006 pour les quinaires de groupe BEGIN { FS= "\t" lie= 0 # pour démarrer correctement la génération de code des liés div= 16 # diviseur (ex. pour la noire) batt= 60 # battement (ex. 60 battements par minute) ennaire= 2 # utile pour les groupes d'exceptions à la mesure uNote["q"]= 1 # unités notes uNote["t"]= 2 uNote["t."]= 2+uNote["q"] uNote["t.t"]= 2+uNote["q"]+uNote["t"] # juste pour diviseur uNote["f"]= 4 uNote["f."]= 4+uNote["t"] uNote["f.f"]= 4+uNote["t"]+uNote["f"] # idem uNote["f.."]= 4+uNote["t"]+uNote["q"] uNote["["]= 8 uNote["[."]= 8+uNote["f"] uNote["[.["]= 8+uNote["f"]+uNote["["] # idem uNote["[.."]= 8+uNote["f"]+uNote["t"] uNote["!"]= 16 uNote["!."]= 16+uNote["["] uNote["!.!"]= 16+uNote["["]+uNote["!"] # idem uNote["!.."]= 16+uNote["["]+uNote["f"] uNote["d"]= 32 uNote["d."]= 32+uNote["!"] uNote["d.d"]= 32+uNote["!"]+uNote["d"] # idem uNote["d.."]= 32+uNote["!"]+uNote["["] uNote["o"]= 64 uNote["o."]= 64+uNote["d"] uNote["o.o"]= 64+uNote["d"]+uNote["o"] # idem uNote["o.."]= 64+uNote["d"]+uNote["!"] uNote["w"]= 1 # unités silences uNote["x"]= 2 uNote["x."]= 2+uNote["w"] uNote["k"]= 4 uNote["k."]= 4+uNote["x"] uNote["k.."]= 4+uNote["x"]+uNote["w"] uNote[">"]= 8 uNote[">."]= 8+uNote["k"] uNote[">.."]= 8+uNote["k"]+uNote["x"] uNote["<"]= 16 uNote["<."]= 16+uNote[">"] uNote["<.."]= 16+uNote[">"]+uNote["k"] uNote["="]= 32 uNote["=."]= 32+uNote["<"] uNote["=.."]= 32+uNote["<"]+uNote[">"] uNote["-"]= 64 uNote["-."]= 64+uNote["="] uNote["-.."]= 64+uNote["="]+uNote["<"] } { if ( NF > 7 ) { split($1, a, "[ ]*=[ ]*") # récupérer la valeur du temps et son battement # valeur-échelon div= uNote[a["1"]] batt= a["2"] # modification possible par valeur extérieure if ( bat != 0 ) batt= bat #fixe ennaire pour les groupes exception à binaire, ternaire, quinaire, septnaire split($3, chg, "[ ]*/[ ]*") if ( 0 == chg[1] % 7 ) ennaire = 7 else if ( 0 == chg[1] % 5 ) ennaire = 5 else if ( 0 == chg[1] % 3 ) ennaire = 3 else if ( (0 == chg[1] % 2) || chg[1] == 1 ) ennaire = 2 else { # pas d'erreur en decompo ennaire = chg[1] # peut-être premier ou quasi-premier } #print "chg ", ennaire # de'bogage print "# ", $1, $6 notes($6) # fournie un tableau de notes : tabNotes # Il s'agit d'un code intermédiaire à afficher à des fins de débogage # i= 1; while(tabNotes[i] != "") { print tabNotes[i]; i++ } genereCode(tabNotes) if ( match($6, /\|/) ) print "" # ou index($6, "|") } } END {} function notes(temps) { i= 1 # indice dans tabNotes[] j= 0 # compteur pour dépassement (sécurité) k= 0 # compteur de notes, silences x= 1 # indice de début du groupe dans tabNotes[] grp= 0 # booléen d'entrée/sortie d'un groupe ( [ [ [ )3 delete tabNotes while( temps != "" && temps != " " && temps != "|" && temps != " |" && j < 500 ) { # pour la préparation des notes, silences en triolet, quintolet, etc # besoin de match pour substr et non index, autorise plusieurs triolet if ( match(temps, "[(]") == 1 ) { grp= 1 # entrée dans un groupe k= 0 # compter à partir de maintenant x= i # indice qui compte maintenant temps= substr(temps, 1, RSTART-1) substr(temps, RSTART+RLENGTH) } if ( match(temps, "[)][2-9]?") == 1 ) { deb= RSTART; fin= RLENGTH; grp= 0 if ( match(temps, "[2-9]") == 2 ) k= substr(temps, 2, 1) # indication de groupe if ( index(temps, "_") == deb+fin) { # cas ")_" ou ")[2-9]_" tabNotes[i-1]= "_" tabNotes[i-1] # préfixé par lié for(; x < i; x++) tabNotes[x]= k tabNotes[x] # préfixé par symbole du groupe temps= substr(temps, 1, deb-1) substr(temps, deb+fin+1) } else { for(; x < i; x++) tabNotes[x]= k tabNotes[x] # préfixé par symbole du groupe temps= substr(temps, 1, deb-1) substr(temps, deb+fin) } continue # redémarrer la recherche à partir de '(' } if ( match(temps, "[qtf[!do]|[tf[!do][.]|[f[!do][.][.]|\ [wxk><=-]|[xk><=-][.]|[k><=-][.][.]") ) { k++ if ( index(temps, "_") == RSTART+RLENGTH) { if (grp) k-- # ne pas prendre en compte les liés de quinaires de groupe tabNotes[i++]= "_" substr(temps, RSTART, RLENGTH) # préfixé par lié temps= substr(temps, 1, RSTART-1) substr(temps, RSTART+RLENGTH+1) } else { tabNotes[i++]= substr(temps, RSTART, RLENGTH) temps= substr(temps, 1, RSTART-1) substr(temps, RSTART+RLENGTH) } } j++ # voir ci-dessous } # pour signaler un éventuel problème de terminaison if (j == 500) { printf("Le temps se termine par \"%s\"\n", temps); exit 1 } } function genereCode(tab) { i= 1 while( tab[i] != "" ) { if ( match(tab[i], "[2-9]") == 1 ) { # facteur pour triolet, quinolet, etc eltGrp= substr(tab[i], RSTART, RLENGTH) if ( eltGrp == 1 ) f = 1 #ici seulment si 1-9 au lieu de 2-9 else if ( ennaire == 7 ) { # affichage pas de msg d'erreur if ( eltGrp == 6 ) f = 7 / 6 else if ( eltGrp == 8 ) f = 7 / 8 } else if ( ennaire == 5 ) { if ( eltGrp == 4 ) f = 5 / 4 else if ( eltGrp == 6 ) f = 5 / 6 else if ( eltGrp == 9 ) f =10 / 9 } else if ( ennaire == 3 ) { if ( eltGrp == 2 ) f = 3 / 2 else if ( eltGrp == 4 ) f = 3 / 4 else if ( eltGrp == 5 ) f = 6 / 5 else if ( eltGrp == 7 ) f = 6 / 7 else if ( eltGrp == 8 ) f = 9 / 8 } else { # binaire, unaire et autre décomposée if ( eltGrp == 3 ) f = 2 / 3 else if ( eltGrp == 5 ) f = 4 / 5 else if ( eltGrp == 7 ) f = 8 / 7 else if ( eltGrp == 9 ) f = 8 / 9 } tab[i]= substr(tab[i], 2) # récupérer juste le symbole sans [2-9] } else f= 1 slie= lie if ( match(tab[i], "_") == 1 ) { # lié lie= 1 tab[i]= substr(tab[i], 2) # récupérer le symbole sans '_' devant } else lie= 0 # match() est-il utile ? juste savoir si c'est une note ou un silence if ( match(tab[i], "[qtf[!do]") ) { if ( slie ) printf("sleep %f\n", 60 / batt * (uNote[tab[i]] / div) * f) else printf("echo -n \nsleep %f\n", 60 / batt * (uNote[tab[i]] / div) * f) } if ( match(tab[i], "[wxk><=-]") ) { if ( slie ) printf("sleep %f\n", 60 / batt * (uNote[tab[i]] / div) * f) else printf("echo -n \nsleep %f\n", 60 / batt * (uNote[tab[i]] / div) * f) } i++ } }