Le
Scalas juste se monstra consister de non tanto multe petras de construction, le intervallos, e.g. 9:8, 10:9, 16:15. Ja con iste tres, multe gammas de musica occidental pote esser construite, e le addition de 11:10 e 12:11, e 17:16 e 18:17, allarga le possibilitates a quasi toto que existe in le mundo.
Musica resimila le universo, que consiste in essentia de quarks, leptones e bosones.
In 2002, e usque alcun dies retro, io faceva le analyse de gammas musical in su elementos ancora a mano, simile al joco Tetris. Isto es laboriose, fatigante e promovente de errores. Computers es ben capabile de calcular, e anque diligente e celere. Proque non lassar illos facer le labor?
Ex iste pensata, le 22–24 de septembre 2023 io ha scribite le programma pilaintv.c, que pila intervallos, in varie combinationes, e cata vice controla si illos insimul pote formar exactemente un octavo, e si le rationes del frequentias del tonos pote esser exprimite como un serie le numeros satis parve.
Multe scalas musical ha 7 grados, e.g. c d e f g a b, ma in le luce de iste serie, que in parte es super un gamma de 14 tonos, io voleva poter calcular con iste maximo. Intertanto io lassa le programma considerar 12 intervallos differente, in principio pro cata grado del scala. 12 ^ 14 = 1.283.918.464.548.864 combinationes a considerar. 1284 billiones in le scala longe de grande numeros. Nimie labor, mesmo pro le computers con precios tolerabile de hodie, que totevia es rapidissime.
Sed ja tosto io me realisava que optimalisationes multo effective serea
possibile. E.g. si on considera le intervallo 9:8 inter le prime e
secunde grado, e le mesme 9:8 pro le proxime (un
approche
pythagoric), le ration ja es 81:64, non reducibile. Pilar ancora
un tal intervallo causarea un ration de 729:512, numeros vermente
troppo grande, ergo il non es sensate continuar in iste branca del
arbore de combinationes. Isto es le constante MAXFACT
,
que actualmente ha le valor de 90, definite in le programma assi
que alterar lo require un nove compilation. Forsan io deberea facer
tote iste parametros configurabile foras del programma mesme. Ma non
ora.
Mi programma contine:
if (wS[grado].cumulated.numer > MAXFACT) { cnt_factor++; continue; }
Ergo io conta le essayo, ma salta tote le altere combinationes in le branca actual. Initialmente io considerava scriber 14 buclos for annidate, ma illo es inflexibile, e le labor non solo debe esser facite in le buclo for le plus profunde, ma in totes, pro cata grado del scala musical. Le solution provava, como io ja ha experimentate plus sovente, le uso de un algorithmo recursive. Illo sembla forsan difficile e riscose, ma non lo es.
Il ha in le texto del programma ora solo un buclo for, ben, il
ha plus, ma le buclo essential occurre solo un vice, in le function
que io ha aptemente appellate recurs
, que al fin, post
considerar tote le rationes potential pro NON
continuar in iste branca, invoca se mesme, pro le proxime grado:
recurs(grado + 1);
Le mecanismo del recursion, in collaboration con le compilator C e le
stack del processor, causa que iste sol buclo for
al mesme tempore pote esser active pro multe grados del scala
musical, e via le variabile local ivl
, le statement
permuta in illos le intervallos offerite pro inclusion in le scala.
Multo effective, efficiente, e elegante e automatic.
Ora in vice de facer 1.283.918.464.548.864 essayos, le programma reporta iste summas, per exemplo:
1149276: numerator exceeds 90 529355: ratio overshoots 2.0 46664: least common multiple exceeds 125 0: not according to specs 3202: valid scales
Dunque in plus que un million casos, le rationes del intervallos considerate pro construer un scala, resulta in un ration pro un grado del scala, que ja es tro grande. Ille approcha non va trovar un bon solution, il non es sensate continuar lo, ration pro le programma pro abandonar iste branca, e continuar con altere intervallos.
In medie million de casos, le octavo es attingite, ma non exactemente: un proxime intervallo resulta in un ration plus grande que 2:1 o 1200 cents. Un tal resultato es anque invalide: le octavo debe sempre esser parte de un scala, e exactemente.
In plus que 45.000 casos, un scala poteva esser calculate, ma quando le programma essayava facer del rationes un serie de numeros integre, que ha iste rationes e intervallos, le numeros deveniva troppo grande. Non elegante, non sona ben, ergo le scale esseva abandonate.
Il remaneva plus que 3000 scalas valide, cuje detalios le programma
ha scribite al canal stdout
, o a un file si le
output, le sortita, es deviate in le linea de commandos.
Le tempore usate es:
real 0m0,261s user 0m0,243s sys 0m0,004s
Dunque minus que un quarto de un secunda basta pro facer tote iste calculationes. Isto include scriber 1.801.729 bytes a un file de texto.
Un exemplo del sortita del programma:
24 27 30 32 36 40 45 48 1 0 0.000 0.000 0/53 24 1:1 -- 1 2 200 203.910 203.774 9/53 27 9:8 -- 9:8 203.910 2 3 400 386.314 384.906 17/53 30 5:4 -- 10:9 182.404 3 4 500 498.045 498.113 22/53 32 4:3 -- 16:15 111.731 4 5 700 701.955 701.887 31/53 36 3:2 -- 9:8 203.910 5 6 900 884.359 883.019 39/53 40 5:3 -- 10:9 182.404 6 7 1100 1088.269 1086.792 48/53 45 15:8 -- 9:8 203.910 7 8 1200 1200.000 1200.000 53/53 48 2:1 -- 16:15 111.731 8 I II III IV V VI VII VIII IX X XI
Columna VI, que plus tarde appare verticalmente insimul con altere datos, primo appare in un sol linea in direction horizontal, pro facilitar cercas de texto pro certe scalas.
Explanation del columnas:
De novo le exemplo:
I II III IV V VI VII VIII IX X XI 24 27 30 32 36 40 45 48 1 0 0.000 0.000 0/53 24 1:1 -- 1 2 200 203.910 203.774 9/53 27 9:8 -- 9:8 203.910 2 3 400 386.314 384.906 17/53 30 5:4 -- 10:9 182.404 3 4 500 498.045 498.113 22/53 32 4:3 -- 16:15 111.731 4 5 700 701.955 701.887 31/53 36 3:2 -- 9:8 203.910 5 6 900 884.359 883.019 39/53 40 5:3 -- 10:9 182.404 6 7 1100 1088.269 1086.792 48/53 45 15:8 -- 9:8 203.910 7 8 1200 1200.000 1200.000 53/53 48 2:1 -- 16:15 111.731 8
Le matino del 24 de september 2023 io habeva iste idea: il serea bon si le programma non solo poterea trovar TOTE le scalas intra certe limitationes, ma anque scalas specific secun criteria que le usator dona, nam altores approximate de certe grados del gamma musical.
E le algorithmo tunc ja implementate, esseva facile a extender pro iste functionalitate: simplicemente adde un ration pro rejectar un scala, si illo devia troppo del specificationes donate per le usator. Assi le scala o scalas que compli, remane.
Le predefinition, le default, es le scala de C major. Si
de isto on vole dicer que le tertia debe esser un tertia
minor in vice de un tertia major, ergo ca. 100 cents plus
basse, on invoca le programma assi:
./pilaintv 2 -100
Il ha un par consistente del grado, e le deviation in cents.
Nota que le prime grado hic ha le numero zero, non le
numero un como in le sortita del programma. Isto es pro
melio corresponder con le maniera de specificar scalas special
in Lilypond. On pote anque usar, in vice del numeros, le
litteras (majusculas o minusculas) del tonos del scala de
C major:
./pilaintv e -100
Anque possibile, ma solo con numeros, non litteras, es specificar
cents absolute, in vice del deviation del scala de C major:
./pilaintv -a 2 300
specifica que le grado 2, le tertie grado, del tertia, debe haber
circa 300 cents, non 400 como in un scala major.
In iste exemplos, io ha usate numeros de cents rotundate, ma numeros
plus accurate es anque permittite, per exemplo
./pilaintv -a 2 315.641
Si le numero de cents concorda intra 25 cents (le medie de un
quarto de tono), le programma accepta le intervallo.
In le proxime parte del serie de articulos il ha plus exemplos de usar iste functionalitate.
“Scala” es un programma interessante re scalas e accordos. Multo plus comprehensive, e con un approche multo differente que le mie, io pensa al leger le description. Io non ha mesme usate lo.