¿Qué hace music-skill?
Los scripts viven en scripts/ junto a este archivo; escríbelo como $S abajo, pero escribe la ruta absoluta en cada comando, porque las variables de shell no se transmiten entre llamadas Bash.
No puedes oír, así que cada paso convierte la música en algo que puedes leer: patrones como texto, números que verificas y una imagen que miras. Hacer una pista es semilla → leer la partitura → renderizar → look → arreglar. Entender audio es look → leer la línea de tiempo y la hoja → juzgar. Entregar es check, así que "tiene el volumen correcto y no recortará" es un hecho.
Requiere uv y ffmpeg. Cada comando se ejecuta como uv run --no-project --with numpy --with scipy --with pillow python -I <script> …, escrito como RUN abajo.
Hacer una pista: banger.py
RUN $S/banger.py --seed 4242 --out <scratch>/b4242
Una pista de house o techno de 72 compases toma unos 10 segundos: track.wav (48 kHz estéreo, -14 LUFS), track.mid, score.txt y score.json. La misma semilla y opciones siempre dan el mismo archivo.
| Quieres | Opción |
|---|---|
| Un estilo | --style deep-house (120-124 BPM), tech-house (124-128), peak-techno (130-136), melodic-techno (122-126) |
| Un tempo, una tonalidad | --bpm 124, --key A, --mode minor (o dorian, phrygian) |
| Una duración | --bars 24 (cualquier número par desde 8), o --seconds 30: elige los compases y ajusta el tempo para que el último compás termine 2.5 s antes y la reverberación termine a tiempo |
| Una base bajo una voz | --lufs -22 --mute lead (también prueba silenciado clap) |
| Partes para un DAW o revisión de mezcla | --stems escribe stems/<layer>.wav; track.mid siempre se escribe |
Los compases deciden la forma: 8-10 es un loop; 12-22 es intro, drop, outro; 24-46 añade un breakdown y un build-up entre dos drops; 48 o más es la forma completa con una sección de groove y partes de 8 compases.
Lee la partitura antes de renderizar más. Imprime los patrones como texto:
seed 4242 Melodic techno 122 BPM G minor swing 1% chords: pluck
1...2...3...4...
kick X...X...X.X.X...
clap .o..X.......X...
hat x.X...X.x.X...X.
bass .....ORO.O.O3RRR
chords ...X............ i7 Gm7 | bVII7 F7 | bVI7 Ebmaj7 | iv7 Cm7
lead 47244.42.22..442 .3315.553.5.3557
perc fit 74% 1293 patterns tried weakest: Evenly spread 52%, Clear mix 20%
. silencio, o suave, x medio, X fuerte. Bajo: R tónica, 5 quinta, O octava, 3 tercera. Líder: grado de escala 0-9 en dos compases. fit es qué tan bien cumple la parte sus reglas; weakest nombra las reglas que falló.
Para elegir una semilla, audiciona como texto primero: python3 $S/groove.py --seed N ejecuta solo la búsqueda (0.5 s, sin audio, sin dependencias). Prueba unas cuantas, lee los acordes y el líder, renderiza la que defenderías. No puedes juzgar "suena bien": dilo y dale a la persona el archivo.
Cómo se escribe una pista
El método es de Banger Lab. Es búsqueda, no un modelo, y cada regla proviene de un estudio de la percepción del ritmo o el tono.
- Rodar. La semilla elige un estilo, tempo, tonalidad, escala y objetivos: hi-hats por compás, cuánta síncopa, cuántos acordes diferentes.
- Adivinar. Cada instrumento comienza como un patrón aleatorio de 16 pasos.
- Probar. Cada cambio de un paso (añadir, quitar, deslizar, más fuerte, más suave) se puntúa contra las reglas de ese instrumento, más algunos saltos aleatorios de dos pasos. Se conserva el mejor.
- Bloquear. Cuando ningún cambio puntúa más alto, la parte está lista y el siguiente instrumento se escribe sobre ella. Orden: kick, clap, hi-hat, open hat, percusión, bajo, acordes, líder. Cada capa obtiene cuatro inicios aleatorios y se queda con el mejor.
- Escuchar.
banger.pyrenderiza cada instrumento solo, mide dónde está su energía en seis bandas, y un segundo pase reajusta hi-hats, percusión, bajo, acordes y líder para que las partes no llenen la misma banda en el mismo paso. - Arreglar. Las partes se convierten en secciones, con fills al final de cada 4 y 8 compases, un filtro paso bajo que se abre durante el breakdown, un redoble de caja y riser en el build, un tiempo de silencio, y luego el drop.
Lo que hace que groove: las reglas
Úsalas cuando escribas o edites música por cualquier medio: un patrón a mano, MIDI o un prompt para un modelo musical. score.json tiene la puntuación de cada regla y su fuente para una pista.
| Parte | Regla | Fuente |
|---|---|---|
| Kick | en cada tiempo; como máximo 0-2 extras, colocados justo antes de un tiempo; nunca dos seguidos | Butler 2006 |
| Clap | fuerte en los tiempos 2 y 4, fuera de los tiempos 1 y 3; los extras son suaves y en semicorcheas débiles | Butler 2006; Witek 2014 |
| Hi-hats | en los contratiempos, entre los kicks; distribuidos uniformemente; igual en ambas mitades del compás; fuerte y suave se alternan | Butler 2006; Toussaint 2005 |
| Open hat | a medio camino entre dos kicks, nunca en un kick o clap | Butler 2006 |
| Percusión | distribuida uniformemente, donde kick y clap están en silencio, con 25-50% de notas fantasma suaves | Toussaint 2005; Witek 2014 |
| Bajo | suena donde el kick no lo hace; tónica (o su octava) 60-90% del tiempo, quinta o tercera para color | Plomp & Levelt 1965; Krumhansl & Kessler 1982 |
| Acordes | el compás 1 es el acorde principal; las raíces se mueven por paso, tercera o cuarta; cada voz se mueve el camino más corto al siguiente acorde | Krumhansl & Kessler 1982; Tymoczko 2011 |
| Líder | notas del acorde en tiempos fuertes; nunca un semitono por encima de una nota del acorde; pasos pequeños; compás 1 pregunta (termina fuera de la nota principal), compás 2 responde con un ritmo similar (termina en ella); suena en los huecos entre los golpes de acorde | Plomp & Levelt 1965; Huron 2001; Caplin 1998 |
| Todo | síncopa media: algunas notas en pasos débiles que saltan uno fuerte. Demasiado poco es rígido, demasiado pierde el ritmo | Witek et al. 2014 |
| Timing | swing y push/pull se mantienen por debajo de 12 ms por instrumento (hi-hats tarde, clap temprano). Desplazamientos mayores redujeron las valoraciones de groove | Davies et al. 2013 |
| Mezcla | dos partes en la misma banda en el mismo paso se difuminan mutuamente; no más de 4 partes golpeando un paso | Plomp & Levelt 1965 |
| Forma | breakdown, build-up y drop: quita el kick y el bajo, aumenta la tensión, tráelos de vuelta | Solberg & Dibben 2019; Butler 2006 |
Cada nota proviene de una escala y el kick está afinado a la nota principal, por lo que cualquier semilla se mantiene en tonalidad. Los pesos entre reglas son una simplificación, no ajustados a datos de escucha, por lo que fit clasifica patrones dentro de una pista; no es una puntuación de calidad entre pistas.
Escuchar: look
RUN $S/listen.py look TRACK --sheet <scratch>/sheet.png
Funciona en cualquier cosa que ffmpeg decodifique, incluyendo el sonido de un video y música de un modelo generativo. Imprime tempo, tonalidad, loudness, pico verdadero, balance, ancho estéreo, advertencias y una línea de tiempo:
track.wav 2:24.1 122.0 BPM (strength 7.9) G minor (score 1.62; next Eb major 1.61)
loudness -14.0 LUFS true peak -1.3 dBTP range 9.3 LU peak-to-loudness 12.7 dB
balance, dB under the loudest band sub -2 bass 0 low mid -8 mid -17 high -24 air -27
timeline, 15.7 s windows (8 bars): loudness, then each band in dB against its level over the whole track
start LUFS sub bass low mid mid high air
0:47.2 -12.6 +2 +2 +1 +2 +1 -2
1:03.0 -21.1 -29 -12 +1 -7 -7 -6
1:18.7 -20.5 -33 -12 +1 -1 +3 +6
1:34.4 -12.6 +2 +2 +1 +2 +1 -0
Lee la estructura de la línea de tiempo. Sub y bajo 20-30 dB por debajo es un breakdown (kick y bajo están fuera). Alto y aire subiendo mientras sub se mantiene fuera es un build. Todo de vuelta a la vez es el drop. Luego lee la hoja (forma de onda, espectrograma, seis carriles de banda, curva de loudness): un riser es una línea diagonal, un kick es una columna de puntos brillantes en la parte inferior, un bloque plano de color sin espacios es una mezcla sin dinámica. Da los tiempos del eje de la hoja cuando describas un momento.
Qué tan confiable es, medido en 24 pistas renderizadas con respuestas conocidas:
- Tempo: dentro de 0.2 BPM en 24 de 24. Prefiere 70-190 BPM, por lo que la mitad o el doble de tiempo es posible en otro material. Una fuerza por debajo de 2 significa que no hay un ritmo constante: di que el BPM es una estimación.
- Tonalidad: la nota principal fue correcta en 19 de 24, y es menos confiable en audio corto o disperso. Mayor vs menor es una decisión más débil, y no puede distinguir modos. Cuando las dos puntuaciones más altas están cercanas lo dice; informa ambas.
- Loudness y pico verdadero: los mismos números que
ffmpeg -af ebur128=peak=truehasta 0.1.
Stems entre sí: mix
RUN $S/listen.py mix <scratch>/b4242/stems
Por stem: loudness y dónde se encuentra su energía. Luego los pares que más se cubren entre sí (misma banda, mismo momento), y los stems que son muy silenciosos junto al más fuerte. Un par por encima del 60% son dos partes luchando por un espacio: mueve una en tiempo, tono o nivel.
Números a alcanzar, y check
| Objetivo | Número |
|---|---|
| Una pista sola (streaming normaliza cerca de aquí) | -14 LUFS integrado |
| La mezcla final de un video web o podcast | -16 LUFS |
| Una base bajo una voz | aproximadamente -22 LUFS |
| Pico verdadero, siempre | -1 dBTP o menos: la codificación con pérdida sobreexpone |
| Pico a loudness por debajo de 7 dB | demasiado limitado: plano y cansado |
| Correlación estéreo por debajo de 120 Hz por debajo de 0.6 | el bajo puede desaparecer en mono (teléfonos, clubes) |
RUN $S/listen.py check TRACK --lufs -14 --peak -1 --seconds 30 --bpm 124
check debe pasar antes de entregar un archivo; sale con 1 si falla. También detecta recorte y silencio al inicio. La música de un modelo necesita esto más: una base generada midió +3.2 dBTP con 2,121 muestras recortadas. Arregla con ffmpeg (loudnorm=I=-14:TP=-1.5:LRA=11), luego verifica de nuevo.
Entrega
- Copia pequeña:
ffmpeg -i track.wav -c:a aac -b:a 160k track.m4a(o-c:a libmp3lame -q:a 2). Ejecutachecken la copia: la codificación mueve el pico verdadero. - Bajo un video: renderiza con
--seconds <duración del video>y--lufs -22, y entrégaselo a video-skill, que verifica la mezcla final. - Un loop:
--bars 8, luego corta la cola de 2.5 s (-t <8 compases en segundos>) para que se repita limpiamente. - Guarda
score.txtcon el archivo: su última línea es el comando exacto que lo creó.
Cuándo esta es la herramienta equivocada
banger.py hace música electrónica 4/4 a partir de osciladores y ruido. No tiene samples, voces ni otros géneros, y su mezcla es más oscura y estrecha que un lanzamiento masterizado (los medios de la demo están 17 dB por debajo de su bajo). Para instrumentos acústicos, una canción o un estado de ánimo con nombre, usa un modelo musical o una pista de biblioteca, luego ejecuta look y check en lo que devuelva. Lo que esto te da en su lugar: tempo, tonalidad y duración exactos, el mismo resultado de la misma semilla, stems, MIDI, nada que licenciar y una razón para cada nota.
Errores comunes
| Error | Solución |
|---|---|
| Decir que una pista "suena genial" | No la has escuchado. Informa los números y lo que muestra la hoja; la persona juzga el sonido |
| Renderizar 20 semillas para elegir una | groove.py --seed N imprime la puntuación en 0.5 s; renderiza la elegida |
Comparar fit entre pistas | Clasifica patrones solo dentro de una pista |
| Confiar en la tonalidad en un clip de 10 segundos | Da ambos candidatos principales |
Entregar el WAV sin check | Haz check y también verifica la copia codificada |
| Música de un modelo usada tal cual | Primero look: el recorte y los picos +dBTP son comunes |
| Una base que lucha contra la voz | --lufs -22 --mute lead, y mantén 1-4 kHz despejados |