Pipeline DSP para análisis de forma, tempo, espectro, armonía y dinámica
Palabras clave: MIR, análisis musical, FFT, cromagrama, estimación de tonalidad, BPM, segmentación de forma, techno.
El análisis musicológico y la ingeniería de audio tradicionalmente requieren herramientas especializadas (DAW, espectroanalizadores, detectores de tempo). TEXNO unifica en un único flujo automático la extracción de descriptores de bajo y medio nivel que caracterizan una grabación masterizada: tempo, distribución espectral, centroide, dinámica, estructura macro (intro, build, drop, break, outro), pitch classes dominantes y capas estimadas (kick, bajo, percusión, hats, aire).
La salida no pretende reemplazar la escucha crítica ni la separación de fuentes por modelos neuronales; constituye una firma estructural reproducible, útil para catalogación, comparación de mixes, documentación de sets y prototipado de herramientas de remix o recomendación.
El pipeline se organiza en cinco etapas secuenciales:
@audio/decode, lectura ID3/container con music-metadata.
Audio → decode → mono[n] → envelope[] → {BPM, onsets, form, energy_curve}
↘ FFT blocks → {spectrum, chroma, harmony, layers}
Sea xc[n] la señal discreta del canal c a frecuencia de muestreo fs. La mezcla mono se define como:
y[n] = (1/C) · Σc=1C xc[n]
donde C es el número de canales. Esta reducción elimina información de panorámica pero estabiliza estimadores espectrales y de energía en material estéreo ampliamente correlacionado (típico en masters de club).
La señal se divide en tramas de Nf = ⌊fs · Tf⌋ muestras con Tf = 50 ms y salto igual al tamaño de trama (sin solapamiento). Para cada trama k:
E[k] = √( (1/Nf) · Σi=0Nf−1 y[nk+i]² )
La secuencia {E[k]} constituye la envolvente de amplitud y es la base para tempo, onsets, segmentación de forma y curva de energía narrativa.
Se aplica autocorrelación no normalizada sobre la envolvente centrada en media: Ẽ[k] = E[k] − μE. Para cada retardo τ en el rango compatible con 70–180 BPM:
R(τ) = Σk Ẽ[k] · Ẽ[k+τ]
El retardo τ* que maximiza R(τ) se convierte en tempo BPM = 60 · fenv / τ*, donde fenv = 1000/Tf es la tasa de frames de la envolvente. Se aplican reglas de octava para favorecer el rango electrónico (duplicar si BPM < 100, dividir si BPM > 160). La confianza se escala linealmente con R(τ*) respecto a la longitud de la envolvente.
Picos locales en E[k] por encima de θ = 1.4 · μE, con separación mínima de 80 ms entre eventos. La densidad rítmica se reporta como onsets / duración (eventos por segundo).
La señal se analiza en bloques de N = 2048 muestras con ventana de Hann:
w[n] = 0.5 · (1 − cos(2πn / (N−1)))
El avance entre bloques es hop = 4N muestras (~186 ms a 44.1 kHz), reduciendo coste computacional. Se implementa FFT radix-2 in-place (Cooley–Tukey) sobre las componentes real e imaginaria.
Para cada bin k, la magnitud es |X[k]| = √(Re² + Im²) y la frecuencia asociada fk = k · fs / N.
La energía espectral se agrega en cinco bandas estándar de mezcla:
| Banda | Rango (Hz) | Interpretación |
|---|---|---|
| SUB | 20–60 | Sub-graves, kick fundamental |
| LOW | 60–250 | Bajo, cuerpo |
| MID | 250–2000 | Percusión, snare, cuerpo de sintes |
| HIGH | 2000–8000 | Presencia, hi-hats |
| AIR | 8000–20000 | Brillo, ruido, FX |
Cada banda se normaliza dividiendo por la suma total de magnitudes en el rango audible (20 Hz–20 kHz), obteniendo proporciones en [0,1].
Para visualización de espectro completo se definen B = 96 bins logarítmicos entre 20 Hz y 20 kHz. Los bordes de bin siguen:
fi = fmin · (fmax/fmin)i/B
La magnitud por bin se acumula y normaliza por el máximo global, reportándose también en dB relativos: 20 log10(mag).
SC = Σk fk · |X[k]| / Σk |X[k]|
Valores altos del centroide (> 4 kHz) se clasifican como brillo high; entre 2–4 kHz medium; por debajo low.
Para frecuencias entre 55 Hz y 5 kHz, cada bin espectral se proyecta a una clase de altura (pitch class) de 12 semitonos mediante:
MIDI(f) = 69 + 12 · log2(f / 440)
La contribución al cromagrama se pondera por magnitud, con factor 1.35 para f < 400 Hz (énfasis en fundamentales) y 0.7 para f > 2 kHz (atenuación de parciales agudos). El vector de 12 dimensiones se normaliza a suma unitaria.
Se correlaciona el cromagrama con perfiles de sensación de tonalidad para modo mayor y menor (Krumhansl & Kessler, 1982; implementación con correlación de Pearson circular para las 12 transposiciones). La clave y modo con mayor correlación definen la tonalidad estimada. La confianza se mapea desde la correlación máxima:
conf = clamp((rmax − 0.55) / 0.4, 0, 1)
En material electrónico monotonal o altamente percusivo, la confianza armónica puede ser alta estadísticamente pero musicalmente ambigua; debe interpretarse junto al espectro y al género.
Por bloque FFT se registra el pico de mayor magnitud entre 40 Hz y 2 kHz. Los picos globales más fuertes se mapean a notas (nombre + octava) evitando duplicar pitch classes, hasta 8 candidatos, con fuerza relativa normalizada.
Sobre la señal mono completa:
La roughness timbral se categoriza por rango dinámico: < 6 dB compressed, 6–12 dB moderate, > 12 dB open.
La envolvente se agrupa en ventanas de ≈1/16 de la duración total. Cada ventana recibe energía normalizada ê = e / max(e) y una etiqueta heurística:
| Condición | Etiqueta |
|---|---|
| t < 12% duración y ê < 0.45 | intro |
| t > 85% duración | outro |
| ê < 0.35 | break |
| ê < 0.55 | build |
| en otro caso | drop |
Secciones contiguas con la misma etiqueta se fusionan. El número de compases se estima dividiendo la duración de la sección por 4 · 60/BPM (compás 4/4 asumido). La energía por sección se reporta en escala 1–10.
A partir de las proporciones espectrales y el BPM, se infiere presencia de capas instrumentales sin separación de fuentes:
La presencia se clasifica como high, medium o low según umbrales relativos dentro de cada banda.
El objeto JSON/YAML Track DNA contiene los siguientes módulos:
| Módulo | Campos principales |
|---|---|
| track | title, bpm, duration_s, key, sample_rate, codec |
| form | array de {name, start_s, end_s, bars, energy} |
| mix | bands, spectrum_curve[], spectral_centroid_hz, rms_db, peak_db |
| harmony | key, scale, chromagram[12], peaks[], explanation_lines[] |
| rhythm | onset_times_s[], density_events_per_s, bpm_confidence |
| timbre | brightness, roughness |
| narrative | energy_curve[], atmosphere, dominant_element |
| layers | id, role, freq_hint, presence, notes |
| analysis_meta | engine, version, analyzed_at, confidence |
| Parámetro | Valor |
|---|---|
| Tamaño FFT N | 2048 |
| Hop espectral | 4N muestras |
| Trama RMS | 50 ms |
| Bins curva log | 96 |
| Rango BPM | 70–180 (con snapping de octava) |
| Umbral onset | 1.4 × media de envolvente |
Para una pista de duración D segundos a 44.1 kHz, el número de bloques FFT es O(D · fs / (4N)) ≈ O(5.4 · D) bloques por minuto de audio. La FFT domina el coste por bloque con O(N log N).
Extensiones previstas: modelos de separación (Demucs, Spleeter), detección de acordes por HMM/CNN, segmentación con auto-similitud (checkerboard kernel), y calibración perceptual EBU R128.
Documento generado para el proyecto TEXNO v1.1. Código fuente y actualizaciones: https://github.com/GustavoUNAL/TEXNO · MIT License.