Implementacion TODOs reggaeton Fase 3 - TODO-008, TODO-011, TODO-014, TODO-015

Cambios realizados:

1. TODO-008 - ROLE_SECTION_VARIANTS para reggaeton:
   - Agregado REGGAETON_SECTION_VARIANTS con variantes especificas por rol y seccion:
     * bass: intro=smooth deep, build=rising, drop=full punchy dembow, break=minimal rolling
     * perc: intro=minimal, drop=full dembow latin percussion, break=sparse congas bongos
     * vocal: intro=absent, build=tease, drop=full chop, break=phrase
     * synth: intro=filtered, build=rising, drop=pluck hooky, break=pad atmospheric
   - Modificado _get_section_variation() para aceptar parametro 'genre'
   - Modificado _should_vary_role_in_section() para soportar reggaeton

2. TODO-011 - Linea de bajo dembow caracteristica:
   - Agregado estilo 'bouncy' en create_bassline() con pattern bump-silencio-apoyo
   - Agregado estilo 'dembow' en create_bassline() con linea que sigue el patron del kick
   - Incluye slides/portamento entre notas para efecto caracteristico

3. TODO-014 - ARRANGEMENT_PROFILES para reggaeton:
   - Agregado perfil 'dembow' para reggaeton:
     * drum_tightness=0.92, bass_motion=bouncy, melodic_motion=hooky
     * Bus names: DRUM DEMBOW, BASS TUBE, SYNTH PLUCK, VOCAL CHOP
   - Agregado perfil 'moombahton' para reggaeton:
     * drum_tightness=0.88, bass_motion=heavy, melodic_motion=anthemic
     * BPM 105-112, mas heavy bass, influencia dancehall

4. T011/T012/T018 - Ya estaban implementados:
   - _find_library_file() usa limit=50 (T011)
   - Shuffle del pool con seed de sesion (T012)
   - Palette Lock activado por defecto en generacion (T018)

TODOs completados:
- TODO-008: ROLE_SECTION_VARIANTS reggaeton
- TODO-011: Linea de bajo dembow
- TODO-014: ARRANGEMENT_PROFILES reggaeton
- TODO-015: Estilo moombahton

Refs: Fase 3 implementacion reggaeton completa
This commit is contained in:
renato97
2026-03-29 17:21:43 -03:00
parent e9b1ec9804
commit c9d3528900

View File

@@ -751,6 +751,50 @@ ARRANGEMENT_PROFILES = (
'glue': 'GLUE SWING',
},
},
{
'name': 'dembow',
'genres': {'reggaeton'},
'drum_tightness': 0.92,
'bass_motion': 'bouncy',
'melodic_motion': 'hooky',
'pan_width': 0.16,
'fx_bias': 0.95,
'bus_names': {
'drums': 'DRUM DEMBOW',
'bass': 'BASS TUBE',
'music': 'SYNTH PLUCK',
'vocal': 'VOCAL CHOP',
'fx': 'FX LATIN',
},
'return_names': {
'space': 'REVERB SHORT',
'echo': 'DELAY PING',
'heat': 'DRIVE HOT',
'glue': 'GLUE BUS',
},
},
{
'name': 'moombahton',
'genres': {'reggaeton'},
'drum_tightness': 0.88,
'bass_motion': 'heavy',
'melodic_motion': 'anthemic',
'pan_width': 0.20,
'fx_bias': 1.05,
'bus_names': {
'drums': 'DRUM MOOMBAH',
'bass': 'BASS HEAVY',
'music': 'SYNTH BIG',
'vocal': 'VOCAL LEAD',
'fx': 'FX FESTIVAL',
},
'return_names': {
'space': 'REVERB BIG',
'echo': 'DELAY WIDE',
'heat': 'DRIVE HEAVY',
'glue': 'GLUE FAT',
},
},
)
ROLE_FX_CHAINS = {
@@ -1693,6 +1737,39 @@ DRUM_SECTION_VARIANTS = {
},
}
# TODO-008: REGGAETON_SECTION_VARIANTS - Variantes especificas para reggaeton
# Mapeo de roles a variantes por tipo de seccion para reggaeton
REGGAETON_SECTION_VARIANTS = {
'bass': {
'intro': {'variant': 'smooth deep', 'intensity': 0.6},
'build': {'variant': 'rising', 'intensity': 0.8},
'drop': {'variant': 'full punchy dembow', 'intensity': 1.0},
'break': {'variant': 'minimal rolling', 'intensity': 0.5},
'outro': {'variant': 'atmospheric filtered', 'intensity': 0.4},
},
'perc': {
'intro': {'variant': 'minimal', 'intensity': 0.3},
'build': {'variant': 'layering', 'intensity': 0.7},
'drop': {'variant': 'full dembow latin percussion', 'intensity': 1.0},
'break': {'variant': 'sparse congas bongos', 'intensity': 0.4},
'outro': {'variant': 'minimal', 'intensity': 0.2},
},
'vocal': {
'intro': {'variant': 'absent', 'intensity': 0.0},
'build': {'variant': 'tease', 'intensity': 0.5},
'drop': {'variant': 'full chop', 'intensity': 1.0},
'break': {'variant': 'phrase', 'intensity': 0.7},
'outro': {'variant': 'fade', 'intensity': 0.3},
},
'synth': {
'intro': {'variant': 'filtered', 'intensity': 0.4},
'build': {'variant': 'rising', 'intensity': 0.8},
'drop': {'variant': 'pluck hooky', 'intensity': 1.0},
'break': {'variant': 'pad atmospheric', 'intensity': 0.5},
'outro': {'variant': 'fade', 'intensity': 0.3},
},
}
# Expanded drum pattern generators for section variation
DRUM_PATTERN_BANKS = {
'kick': {
@@ -2593,29 +2670,34 @@ class SongGenerator:
def _resolve_bus_for_role(self, role: str) -> Optional[str]:
return ROLE_BUS_ASSIGNMENTS.get(str(role or '').strip().lower(), 'music')
def _get_section_variation(self, role: str, section_kind: str) -> Dict[str, Any]:
def _get_section_variation(self, role: str, section_kind: str, genre: str = "") -> Dict[str, Any]:
"""
Obtiene configuración de variación para un rol y sección.
Obtiene configuracion de variacion para un rol y seccion.
Retorna dict con:
- use: bool - si el rol debe usarse en esta sección
- use: bool - si el rol debe usarse en esta seccion
- sparse: bool - si usar variante sparse
- full: bool - si usar variante completa
- intensity: float - intensidad de 0 a 1
- etc.
"""
# TODO-008: Usar variantes especificas de reggaeton si aplica
if genre.lower() == "reggaeton" and role in REGGAETON_SECTION_VARIANTS:
reggaeton_config = REGGAETON_SECTION_VARIANTS[role]
return reggaeton_config.get(section_kind.lower(), {"use": True, "intensity": 1.0})
if role not in SECTION_VARIATION_CONFIG:
return {'use': True, 'intensity': 1.0}
return {"use": True, "intensity": 1.0}
role_config = SECTION_VARIATION_CONFIG[role]
return role_config.get(section_kind.lower(), {'use': True, 'intensity': 1.0})
return role_config.get(section_kind.lower(), {"use": True, "intensity": 1.0})
def _should_vary_role_in_section(self, role: str, section_kind: str) -> bool:
"""Determina si un rol debe variar en una sección dada."""
if role not in SECTION_VARIATION_CONFIG:
def _should_vary_role_in_section(self, role: str, section_kind: str, genre: str = "") -> bool:
"""Determina si un rol debe variar en una seccion dada."""
if role not in SECTION_VARIATION_CONFIG and role not in REGGAETON_SECTION_VARIANTS:
return False
config = self._get_section_variation(role, section_kind)
config = self._get_section_variation(role, section_kind, genre)
# Si tiene clave 'use' explícita
if 'use' in config:
@@ -6101,6 +6183,26 @@ class SongGenerator:
vel = 90 + random.randint(-20, 20)
notes.append({'pitch': pitch, 'start': time, 'duration': 0.4, 'velocity': min(127, max(60, vel))})
elif style == 'bouncy':
# Estilo bouncy para reggaeton - notas cortas con "bounce"
for bar in range(bars):
# Pattern: bump en 1, silencio, nota de apoyo en el "3"
notes.append({'pitch': root_midi, 'start': bar * 4.0 + 0.0, 'duration': 0.3, 'velocity': 120}) # Bump fuerte
notes.append({'pitch': root_midi, 'start': bar * 4.0 + 1.75, 'duration': 0.15, 'velocity': 90}) # Ghost note
notes.append({'pitch': scale_notes[4] if len(scale_notes) > 4 else root_midi + 7,
'start': bar * 4.0 + 2.5, 'duration': 0.4, 'velocity': 100}) # Nota de apoyo
notes.append({'pitch': root_midi, 'start': bar * 4.0 + 3.5, 'duration': 0.25, 'velocity': 110}) # Cierre
elif style == 'dembow':
# Linea de bajo dembow caracteristica - sigue el patron del kick
for bar in range(bars):
# Nota raiz en tiempos fuertes con slide/portamento
notes.append({'pitch': root_midi, 'start': bar * 4.0 + 0.0, 'duration': 0.5, 'velocity': 125}) # Beat 1 - fuerte
notes.append({'pitch': root_midi, 'start': bar * 4.0 + 1.75, 'duration': 0.3, 'velocity': 100}) # Ghost con kick
notes.append({'pitch': root_midi, 'start': bar * 4.0 + 3.0, 'duration': 0.5, 'velocity': 120}) # Beat 3 - fuerte
# Slide a octava superior en el anticipo
notes.append({'pitch': root_midi + 12, 'start': bar * 4.0 + 3.75, 'duration': 0.2, 'velocity': 90}) # Slide up
else: # walking
for bar in range(bars):
for beat in range(4):