¿Genera aleatoriamente y programáticamente un siguiente acorde "bueno"?

Soy un desarrollador de software/músico que tiene tiempo libre antes de que comiencen las clases de verano. Quería agudizar mis habilidades de lectura de acordes e improvisación.

Lo que me gustaría hacer es generar una frase de longitud variable que tenga acordes generados pseudoaleatoriamente. No quiero usar acordes completamente aleatorios porque no creo que eso suene bien o sea divertido de tocar.

¿Hay reglas a seguir al crear una progresión o "siguiente acorde" que le dará una mayor probabilidad de hacer algo que suene bien, y es ese método mejor que lo que obtendría con solo usar acordes generados completamente al azar?

Lo que estoy visualizando en este momento es algo parecido a obtener 8 o 16 compases de una hoja principal, con acordes interesantes para leer a primera vista y practicar durante el día. Realmente no me importa una melodía en este momento. Por lo que he leído, actualmente incluso los mejores investigadores de IA tienen problemas para crear melodías para una progresión determinada.

Hay algunas investigaciones sobre esto usando IA, pero creo que es un poco exagerado para lo que estoy tratando de hacer mateuszdorobek.pl/publication/Jazz-chords-generation
Me gusta jugar con las inversiones y la armonía negativa. Y saltando entre octavas. Y silbatos de lobo. Y tocando notas como un balancín u otras variantes. Y mezclando acordes/melodía, y jugando con volumen, intensidad y repetición.
Creo que un silbato de lobo que tiene la forma de un acorde completo es genial, pero suena un poco robótico, así que tal vez no los rocíe todo el tiempo.
Consulte el software Band-in-a-Box de PG Music. Tiene una función llamada rearmonizar, que suena como lo que te gustaría hacer. Sin embargo, requiere una melodía para trabajar. No sé cómo se le ocurren las progresiones al software, pero estoy seguro de que hay una programación interesante detrás.
Si hiciéramos todos los acordes sus4s, ¿la posibilidad de que cualquier progresión aleatoria de acordes (hecha de esos) sonara decente o mejor aumentara?
Tal vez en.wikipedia.org/wiki/Markov_chain sea interesante para ti
Las redes neuronales con memoria a corto plazo (LSTM) probablemente funcionarían bien aquí. Un poco complicado porque primero tienes que entrenarlo con la música existente, pero probablemente podrías hacer que un ejemplo de juguete funcione relativamente bien con relativamente poco esfuerzo.

Respuestas (10)

Hay varios "mapas de acordes" en la red que indican sucesiones de acordes; estos pueden ser un buen punto de partida. Los mapas de cuerdas no otorgan pesos ni probabilidades relativas a las cuerdas.

Una Cadena de Markov simple también es un buen modelo (pero muy limitado). La idea es generar aleatoriamente (con probabilidades indicadas) la probabilidad de una sucesión de acordes. Versión trivial:

I -> V .40
I -> IV .60
IV -> I .30
IV -> V .70 
V -> I 1.00

Esta matriz de transición puede expandirse; es demasiado miope (solo en el fondo de 3 acordes) para generar algo que suene bien. Se podría hacer un sistema de dos (o más) pasos, pero eso rápidamente se vuelve grande (no es difícil de programar, solo tedioso). Nuevamente, no captura funciones de largo alcance.

Probé (pero no muy en serio) una cadena de Markov con información adicional (V -> I se vuelve más probable a medida que aumenta la longitud de la cadena). Se puede usar otra información secundaria para patrones de largo alcance.

Como se señaló en otras respuestas, algunos movimientos de stock (I -> ii6 -V7) pueden dividirse y tratarse como un solo objeto (como podría ser ii0-I64-V7-I o similar).

Hay muchos trabajos sobre el tema. Uno puede buscar en Google Scholar para encontrar cosas interesantes.

Gramáticas formales

He hecho algunas investigaciones sobre gramáticas formales para la composición. Una gramática formal G = (V, S, P) consta de un vocabulario V , un símbolo inicial S en V y reglas de reemplazo P . Una regla consta de un lado izquierdo (LHS) que describe lo que puede reemplazar y un lado derecho (RHS) que describe el reemplazo. Si desea modelar progresiones armónicas, su vocabulario consistiría en acordes. Considere esta gramática de acordes simple que acabo de inventar:

V = {I, IV, V}
S = I
P = {
  p1: I  -> V I
  p2: V  -> I IV
  p3: IV -> I
}

Comenzamos con S en el paso 0 . Para cada paso, elegimos un símbolo aleatorio en la oración y elegimos una regla aleatoria que tiene el símbolo LHS. Luego reemplazamos el símbolo en la oración con el RHS de la regla. Esto se puede repetir hasta que no se puedan reemplazar más símbolos (en este caso indefinidamente). Aquí hay un ejemplo:

paso regla oración
0 - I
1 p1 V I
2 p2 I IV I
3 p1 I IV V I
4 p1 I IV V V I
5 p2 I IV I IV V I
6 p3 I IV I I V I

Gramáticas de acordes complejas

Steedman 1 define una gramática para Jazz de 12 compases:

reglas de sustitución de acordes para jazz de 12 compases por Steedman

Otro ejemplo de Rohrmeier 2 (no se muestran todas las reglas):

reglas de sustitución de acordes de Rohrmeier

Quick y Hudak 3 utilizan probabilidades de selección y un superíndice que indica la duración del acorde :

Gramática de gráficos temporales probabilísticos para la progresión armónica de Quick y Hudak

Estas imágenes fueron tomadas directamente de las referencias a continuación. No explicaré la sintaxis y las operaciones aquí; por favor lea los documentos completos.

Comparación con el aprendizaje automático

Si bien el aprendizaje automático, en particular las redes neuronales artificiales (ANN), son muy capaces de resolver tareas de lenguaje, las gramáticas (y los sistemas tradicionales basados ​​en reglas en general) tienen algunas ventajas:

  • Simple: es esencialmente solo un reemplazo de cadena. Configurar una ANN es más complejo.
  • Transparente: Está claro por qué la gramática hace lo que hace. Las RNA son "cajas negras".
  • Flexible: si no está satisfecho, cambie las reglas. Las ANN necesitan ser reentrenadas.

La desventaja es que tienes que idear el modelo. Las gramáticas no "aprenden" de los datos. Pero también se pueden combinar y se han combinado con enfoques de ML.

Las cadenas de Markov y las matrices de transición son algo ortogonales a las gramáticas que muestro aquí. Con el primero desarrollas la progresión en la dirección de la línea de tiempo. Con este último desarrollas la progresión de lo abstracto a lo concreto y toda la línea de tiempo a la vez. Creo que ambos enfoques tienen méritos. Al menos con las gramáticas libres de contexto, pierdes el aspecto direccional.

Conclusiones

Las gramáticas son fáciles de configurar y apropiadas para la tarea. Puede crear sus propias reglas o usar gramáticas existentes de la literatura. ¡Pruébalos!


Referencias

  1. Mark Steedman. El blues y la verdad abstracta: Música y modelos mentales. Modelos mentales en ciencia cognitiva , páginas 305–318, 1996.

  2. Martín Rohrmeier. Un enfoque de gramática generativa a la estructura armónica diatónica. En Proceedings of the 4th sound and music computing conference , páginas 97–100, 2007.

  3. Donya Quick y Paul Hudak. Una gramática gráfica generativa temporal para la estructura armónica y métrica. En Actas de la Conferencia Internacional de Música por Computador , 2013.


Recomiendo leer Gramáticas de grafos temporales probabilísticos 3 . Donya Quick desarrolló aún más Kulitta , que es una biblioteca de Haskell para la composición automática que utiliza dichas gramáticas para generar progresiones armónicas.

Esta es una respuesta fascinante: le agregaría una sección en ML. Una aplicación de ML podría ser generar un conjunto de combinaciones de acordes, representando cada acorde en relación con el otro como un vector (no es una tarea sencilla), luego hacer que uno o más humanos proporcionen una calificación de qué tan bien suena la progresión de acordes. En este enfoque, podría "enseñar" al modelo cómo encontrar combinaciones estéticamente agradables mediante la observación de patrones en los acordes que, de otro modo, serían difíciles de reconocer. Dado que las progresiones de acordes son cortas, sería rápido dar a cada una una calificación a mano.
@PaulHazen Gracias, estoy de acuerdo, las gramáticas son fascinantes. Lo que describe suena como algo cercano a una cadena de Markov (primer orden, si solo se usan pares de acordes). Si bien podría usar evaluadores humanos, las matrices de transición generalmente se entrenan en progresiones existentes. Esencialmente, puedes aprovechar el gusto estético de los maestros compositores. Aún así, las cadenas de Markov también tienen inconvenientes. Por ejemplo, carecen de una estructura a gran escala, que se puede lograr fácilmente con gramáticas.
"... hasta que no se puedan reemplazar más símbolos (en este caso indefinidamente)", este es el verdadero problema/desafío en lugar de elegir el "próximo acorde". Es la diferencia entre una divagación sin sentido y una frase sensata. El ejemplo de Steedman parece resolver el problema, porque es una serie de sustituciones/inserciones en un blues de 12 compases, una estructura de frase predeterminada, no realmente un siguiente generador de acordes.
@MichaelCurtis Mi ejemplo simple se repite indefinidamente, pero también puede ser muy preciso sobre qué abstracciones aparecen en qué nivel de la derivación. Con una gramática libre de contexto, obtienes la oración como las hojas de una estructura de árbol. Esa estructura de árbol puede contener frases, compases, tensión/liberación, cualquier organización jerárquica en realidad. Es por eso que prefiero las gramáticas como base sobre las cadenas de Markov, etc. Permiten la automatización y la aleatorización de una manera muy deliberada, a costa de tener que pensar en cómo debería verse la pieza generada.

Un enfoque inicial razonable es elegir una clave, generar un primer acorde, tratando cada nota como una voz independiente, luego, para los acordes posteriores, cambiar una o dos notas (voces) en uno o dos semitonos cada una, manteniéndose dentro de la armadura.

Eso le dará una serie de acordes con una conducción de voz suave, que es un elemento importante para crear progresiones de acordes agradables. Una vez que vea los tipos de secuencias que obtiene, puede refinar el algoritmo. Por ejemplo, puede haber restricciones en términos de cuántos movimientos se pueden hacer en una dirección, o si se requieren dos notas para moverse en la misma dirección o en direcciones diferentes.

Si realmente quiere entrar en el meollo de las cosas, busque una copia (o un resumen en línea, tal vez) de El estudio del contrapunto de Johann Fux y codifique las reglas para la "primera especie" en tres o cuatro voces.


Para generar una frase completa, probablemente sea más fácil usar el "modelo de frase", lo que significaría incluir un acorde tónico, predominante, dominante y nuevamente tónico, en ese orden. Dado que generará acordes diatónicos (con el algoritmo anterior), puede codificar las funciones de cada tipo de acorde para hacer un análisis aproximado de los acordes que se generan.

Me gusta el enfoque, aunque no parece exactamente adecuado para la etiqueta Jazz que tiene el OP en la pregunta.

AI y asistido por computadora no son lo mismo. La verdadera IA es muy difícil, porque la computadora tiene que inferir todos los patrones a partir de prueba y error.

Pero en su caso, podría programar fácilmente lo siguiente:

  • patrones de cadencia comunes
  • reglas sobre el movimiento por ciclo de quintas o por terceras
  • variantes de acordes
  • varios patrones modulatorios, incluyendo séptimas disminuidas enarmónicas.

Personalmente, recomendaría usar una serie de tablas SQL para definir niveles crecientes de complejidad. Por ejemplo, podría definir tipos de acordes y sus inversiones en una tabla. Otra tabla listaría secuencias de acordes e inversiones que combinan bien, desde simples progresiones de dos acordes hasta cadencias más complejas.

Lo bueno de hacerlo de esta manera sería que se podrían usar tablas adicionales para organizar procesos más complejos (como modular a una tecla un segundo menor hacia abajo).

También puede hacerlo progresivamente: comience con solo un par de cadencias simples y algunos movimientos armónicos simples, y luego agregue nuevas variantes y complejidades a medida que desarrolla el sistema.

Por cierto, no solo estoy especulando como compañero pianista, también soy bastante activo en stackoverflow. Probablemente podría convencerme de colaborar en algo como esto, porque a veces he pensado en hacerlo también. :D

Desglosando esto en partes:

  1. Para mejorar tus habilidades de lectura de acordes, te recomiendo que consigas un libro real (o dos) y un metrónomo. Abre el libro real en una página aleatoria y ajusta el metrónomo a un ritmo desafiante. Para variar, hazte una lista de géneros y elige entre ellos también (por ejemplo, swing, bossa, samba, balada doble, etc.). Cuando suene el metrónomo trata de leer toda la pieza sin parar y grábate. Luego puede revisar la grabación y ver con qué secciones tuvo problemas. La ventaja de este enfoque es que utilizará secuencias de acordes reales que probablemente encontrará al tocar. Howard Roberts tenía un método de guitarra que recomendaba hacer algo similar a esto (técnica de guitarra de jazz en 20 semanas).

  2. Para responder a la pregunta de cómo generarlos en el software, el enfoque más sencillo sería tomar un corpus/conjunto de datos de acordes y entrenar un modelo basado en Markov para predecir nuevas secuencias. Un conjunto de datos de ejemplo está aquí https://github.com/infojunkie/ireal-musicxml aunque es posible que deba realizar un procesamiento adicional para obtener los acordes en un formato útil.

¿Hay reglas a seguir al crear una progresión o "siguiente acorde" que le dará una mayor probabilidad de hacer algo que suene bien, y es ese método mejor que lo que obtendría con solo usar acordes generados completamente al azar?

Sí, dos que me vienen a la mente son la dirección de voz y la periodicidad. Para implementar el liderazgo de voz en el software, puede usar los algoritmos sugeridos por Dmitri Tymoczko. Hay una implementación en R aquí: https://github.com/pmcharrison/minVL La periodicidad determina qué tan consonante sonará un acorde para un centro clave dado; hay una investigación en curso para determinar cómo esto da como resultado secuencias de acordes, pero le dará un punto de partida señalar si un acorde dado "suena bien" en comparación con un punto de partida generado aleatoriamente. Consulte https://github.com/pmcharrison/incon para ver varias implementaciones de periodicidad/armonicidad. De esa selección, prefiero Stolzenberg (2015).

Podrías intentar algo que funcione con secuencias armónicas.

Hay un dicho común que dice algo así como "no es un error si lo juegas dos veces" o, en palabras de Adam Neely, "la repetición legitima". La secuencia armónica explota esa idea, porque repites un patrón armónico. Incluso si la progresión es "extraña", la secuenciación a menudo puede convertirla en algo de interés.

Cree algunas plantillas para dos o tres progresiones de acordes (bigramas o trigramas). Puede hacerlo de varias maneras diferentes, pero comenzando con uno de los cuatro acordes de séptima diatónicos y luego avanzando al siguiente acorde por guía de voz o progresión raíz. procedimientos, le dará una gran cantidad de bi-gramas.

Tome la paleta de bi-gramas, seleccione uno al azar, luego secuencialo para tres iteraciones. Seleccione aleatoriamente la dirección ascendente/descendente y medio paso de la distancia de paso completo para la secuencia.

Debería poder rematar el pasaje secuencial con una cadencia completa o media, moviéndose desde el último acorde secuencial por progresión raíz de P4 o P5 a a o iipara Vcomenzar la cadencia debería funcionar. Puede programar eso o hacerlo sobre la marcha como un tipo de ejercicio de mejora.

Eso proporcionará al menos 8 compases y, en la mayoría de los casos, debería tener sentido musical. Si asegura una buena cantidad de variedad en la paleta bi-gram, obtendrá mucha "aleatoriedad". Pero no al azar en el sentido musical de la tontería musical. La secuencia hará que funcione. Pero tres etapas de selección aleatoria (bigrama, dirección de secuencia, distancia de secuencia) proporcionarán muchas progresiones novedosas.

Como no está haciendo esto por razones "serias", sino solo para jugar y mejorar sus habilidades, qué le parece esto: aprenda a trabajar con redes de IA simples (por ejemplo, Tensorflow). Descarga tantas progresiones de acordes como puedas (quizás en forma de tabulaturas gratuitas que hay muchas disponibles). Escriba un pequeño analizador que extraiga solo la progresión de acordes. Entrena tu red con eso. Mira lo que escupe.

Alternativamente, puede intentar capacitar personalmente a la red. Deja que haga lo suyo, toca su progresión en tu propia guitarra y decide por ti mismo si te gusta o no; luego vuelva a introducir esta decisión en el entrenamiento.

Ambos deberían ser ejercicios bastante interesantes y también bastante alcanzables. ¿Crearás la próxima Ópera Rock con esto? Probablemente no. ¡Pero debería ser un pequeño y agradable ejercicio!

Si se siente preparado para la tarea de etiquetar un conjunto de datos y quiere seguir la ruta de la IA, puede probar los LSTM.

Puede elegir una clave musical, y luego cada acorde en la clave sería una variable categórica (tal vez quedarse con solo acordes mayores y menores, y luego incluir extensiones en experimentos posteriores).

Si C->Db->...->Bes 1->2->...->12para mayor y es 13->...->24para menor, entonces la progresión en la clave de C:

C G A Fsería el punto de datos [1 8 10 6],

Cuando tiene un gran conjunto de datos de estos puntos, puede entrenar LSTM.

El paquete python Kerascontiene muchos modelos listos para usar que son útiles. La sintaxis para construir una red neuronal en Keras es (en pseudocódigo):

from keras import Sequential, LSTM, Dropout

model = Sequential()
model.add(LSTM(units = 50, return_sequences = True, input_shape =(4, 1))
model.add(Dropout(0.2))
model.add(LSTM(units = 50, return_sequences = True))

model.fit(training_data)

Otra ventaja de este enfoque sobre la precisión es que puede agregar variables categóricas adicionales al conjunto de datos. Por ejemplo, si desea obtener progresiones de acordes comunes para un género, cuando cree su punto de datos, etiquete también el género.

Entonces, una progresión de acordes en el género rock podría verse así: C G A Fsería el punto de datos[1 8 10 6, 0]

donde el último 0 es género.

El uso general de esto es que si ingresa un acorde inicial, el modelo devuelve los siguientes acordes.

# Pseudocode
input data = [6]
model.predict(input_data)
-> [6, 8, 3, 1]

The best [imo] guide on LSTMs is [here][1]. It assumes familiarity with Neural Networks in general.


  [1]: https://colah.github.io/posts/2015-08-Understanding-LSTMs/

Es más complicado que "dado x acorde, ¿qué podría venir después"? Como eso implica que en una progresión de acordes, n solo está relacionado con n-1, y no con n-2. Tiene razón al esperar que los acordes que suenan totalmente aleatorios no suenen bien. Y aunque hay formas de estar seguro de que el acorde n+1 no sonará fuera de lugar después del acorde n, sonará una función puramente f(n-1) (en general, para el oído que está escuchando toda la progresión con un contexto más grande que 2 acordes en secuencia) igual de aleatorio. Para decirlo de otra manera, si bien es justo decir que "el acorde x puede seguir al acorde y", existe un contexto asumido de una progresión más amplia en la que el acorde x y el acorde y encajan juntos.

Su generador de progresión, para que suene mínimamente aleatorio y malo, debería comenzar eligiendo o generando de alguna manera ese contexto (clave/modo/algún sesgo estilístico para la selección de acordes), y luego trabajar dentro de eso para crear una progresión base y luego opcionalmente modular que basan la progresión en sucesivas repeticiones con variaciones y sustituciones de los acordes de la progresión base.

Podría ser útil crear un modelo de datos del círculo de quintas y modelar internamente los acordes como desplazamientos alrededor del círculo, ya que esto haría que la selección y la sintaxis del código de la descripción de los acordes estuvieran relacionadas entre sí por su centro clave. , y las relaciones entre diferentes centros clave más intuitivas en su código.

Tengo un proyecto (estancado) en el que estaba trabajando para hacer algo similar a esto. También fue un ejercicio de estudio de teoría musical, ya que tuve que aprender muy bien cada teoría-concepto fundamental para poder construir esos conceptos en relación entre sí como clases y objetos, solo para tener un marco base en el que pudiera expresar música. conceptos en código. Durante 2 o 3 semanas, elaboré una arquitectura básica bastante sólida de clases de tono, intervalos y escalas, con pruebas unitarias para usarlas en varias transposiciones y cálculos. Aquí es donde me detuve, pero el siguiente paso habría sido implementar clases inteligentes para construir muchos conceptos de acordes además de los conceptos de intervalo y escala, y luego quizás integrar el círculo de quintas y los centros clave. Solo después de eso habría estado preparado para usar ese marco en algún código de procedimiento para tratar de hacer algo genial como generar música robótica cursi. :)

Desafío de cuadro:

No tiene sentido codificar lo que es una "buena" progresión pseudoaleatoria porque tales modelos ya se explican a través de la teoría musical o el análisis musical. En lugar de usar computadoras para ser creativo, ¿por qué no entender la creatividad del arte existente hecho por humanos para humanos?

La premisa de su pregunta asume una versión idealizada de progresión de acordes "buena". Otra suposición que hace es que puede hacer que una computadora genere algunos acordes "buenos" a través de reglas. Es decir, puede generar una secuencia agradable de acordes sin comprender necesariamente la función o los principios subyacentes de la música, a los que han aludido y referenciado muchas otras respuestas.

Lo que puede hacer un procedimiento es imitar las progresiones existentes, incluso si usa IA (que es solo heurística aplicada).

En lugar de tratar de reducir la música a un par de acordes progresivos o cadenas de Markov, intente examinar y explicar por qué las progresiones comunes le suenan "bien".