Implementacion completa de features reggaeton - Fase 2

Cambios realizados:

1. song_generator.py - Patron dembow MIDI:
   - Agregado pattern_type='dembow' en create_drum_pattern()
   - Pattern caracteristico: kick en 1, 1.75, 3; snare en 2, 3.75; hi-hats 1/8

2. song_generator.py - Progresiones de acordes reggaeton:
   - CHORD_PROGRESSIONS['reggaeton'] con 4 progresiones tipicas:
     * [6,4,1,5] vi-IV-I-V (mas usada)
     * [1,5,6,4] I-V-vi-IV (pop)
     * [6,3,4,1] vi-III-IV-I (trap)
     * [1,1,4,5] I-I-IV-V (romantico)

3. server.py - MASTER_CALIBRATION reggaeton:
   - calibrate_gain_staging() ahora acepta parametro 'genre'
   - Perfil reggaeton: drums=-7, bass=-9, music=-11, vocals=-12
   - Mas punchy y comprimido que techno

4. Libreria reggaeton analizada:
   - Kicks: 4 samples (@dastin.prod)
   - Snares: 7 samples (@dastin)
   - Percs: 4 samples (@dastin.prod)
   - Drum loops: 7 loops (85-96 BPM)
   - reggaeton 2/: bass, drumloops, kick, snare, perc loop

TODOs completados:
- TODO-006: Patron dembow nativo
- TODO-009: MASTER_CALIBRATION reggaeton
- TODO-010: Progresiones acordes reggaeton

Refs: Fase 2 de implementacion reggaeton
This commit is contained in:
renato97
2026-03-29 17:09:29 -03:00
parent c8f03dc47a
commit e9b1ec9804
3 changed files with 322 additions and 10 deletions

View File

@@ -5998,12 +5998,13 @@ def analyze_spectral_fit(ctx: Context, spectral_centroid: float,
# FASE 6: MASTERING & QA TOOLS (T078-T090)
@mcp.tool()
def calibrate_gain_staging(ctx: Context, target_lufs: float = None) -> str:
def calibrate_gain_staging(ctx: Context, target_lufs: float = None, genre: str = "") -> str:
"""
T079: Calibra gain staging del set midiendo y ajustando niveles.
Args:
target_lufs: LUFS objetivo para el master (-8 para club, -14 para streaming)
genre: Genero para aplicar perfil especifico (reggaeton, techno, house)
Mide LUFS de cada bus y ajusta faders para targets:
- Drums (kick): -8 LUFS
@@ -6013,14 +6014,27 @@ def calibrate_gain_staging(ctx: Context, target_lufs: float = None) -> str:
try:
conn = get_ableton_connection()
# Targets por bus
bus_targets = {
"drums": -8.0,
"bass": -10.0,
"music": -12.0,
"vocals": -14.0,
"fx": -16.0
}
# Targets por bus - perfiles por genero
if genre.lower() == "reggaeton":
# Reggaeton: mas comprimido, target LUFS -9 a -8
bus_targets = {
"drums": -7.0, # Mas punchy
"bass": -9.0, # Bajo pesado caracteristico
"music": -11.0, # Brillante
"vocals": -12.0, # Vocales al frente
"fx": -15.0
}
target_profile = "reggaeton_club"
else:
# Perfil estandar (techno/house)
bus_targets = {
"drums": -8.0,
"bass": -10.0,
"music": -12.0,
"vocals": -14.0,
"fx": -16.0
}
target_profile = "club" if target_lufs == -8.0 else "streaming" if target_lufs == -14.0 else "auto"
# Obtener todos los tracks
tracks_response = conn.send_command("get_all_tracks")
@@ -6082,7 +6096,7 @@ def calibrate_gain_staging(ctx: Context, target_lufs: float = None) -> str:
"action": "calibrate_gain_staging",
"tracks_adjusted": len(adjustments),
"adjustments": adjustments,
"target_profile": "club" if target_lufs == -8.0 else "streaming" if target_lufs == -14.0 else "auto",
"target_profile": target_profile,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
}, indent=2)
except Exception as e:

View File

@@ -50,6 +50,12 @@ CHORD_PROGRESSIONS = {
[6, 4, 1, 5], # vi - IV - I - V
[1, 4, 6, 5], # I - IV - vi - V
],
'reggaeton': [
[6, 4, 1, 5], # vi-IV-I-V (la mas usada en reggaeton)
[1, 5, 6, 4], # I-V-vi-IV (pop reggaeton)
[6, 3, 4, 1], # vi-III-IV-I (mas oscura, trap)
[1, 1, 4, 5], # I-I-IV-V (reggaeton romantico)
],
}
# Configuraciones por género
@@ -6013,6 +6019,25 @@ class SongGenerator:
notes.append({'pitch': 40, 'start': bar * 4.0 + 2.0, 'duration': 0.25, 'velocity': 110})
notes.append({'pitch': 42, 'start': bar * 4.0 + 2.5, 'duration': 0.1, 'velocity': 80})
elif pattern_type == 'dembow':
# Patron dembow caracteristico del reggaeton
# K . . . S . K . | K . . . S . . .
# 1 e & a 2 e & a | 3 e & a 4 e & a
for bar in range(bars):
# Kick en 1, 1.75 (el "y" del 2), 3
notes.append({'pitch': 36, 'start': bar * 4.0 + 0.0, 'duration': 0.25, 'velocity': 127}) # Beat 1
notes.append({'pitch': 36, 'start': bar * 4.0 + 1.75, 'duration': 0.25, 'velocity': 115}) # "Ghost" kick
notes.append({'pitch': 36, 'start': bar * 4.0 + 3.0, 'duration': 0.25, 'velocity': 127}) # Beat 3
# Snare/Clap en 2 y 4
notes.append({'pitch': 40, 'start': bar * 4.0 + 1.0, 'duration': 0.25, 'velocity': 110}) # Beat 2
notes.append({'pitch': 40, 'start': bar * 4.0 + 3.75, 'duration': 0.25, 'velocity': 100}) # Anticipo beat 4
# Hi-hats cada 1/8 con swing
for eighth in range(8):
time = bar * 4.0 + eighth * 0.5
# Acentos en 1, 2, 3, 4
vel = 100 if eighth % 2 == 0 else 80
notes.append({'pitch': 42, 'start': time, 'duration': 0.1, 'velocity': vel})
else: # full
notes.extend(self._create_kick_pattern(style, 'standard'))
notes.extend(self._create_clap_pattern(style, 'standard'))