Implement FASE 3, 4, 6 - 15 new MCP tools, 76/110 tasks complete
FASE 3 - Human Feel & Dynamics (10/11 tasks): - apply_clip_fades() - T041: Fade automation per section - write_volume_automation() - T042: Curves (linear, exp, s_curve, punch) - apply_sidechain_pump() - T045: Sidechain by intensity/style - inject_pattern_fills() - T048: Snare rolls, fills by density - humanize_set() - T050: Timing + velocity + groove automation FASE 4 - Key Compatibility & Tonal (9/12 tasks): - audio_key_compatibility.py: Full KEY_COMPATIBILITY_MATRIX - analyze_key_compatibility() - T053: Harmonic compatibility scoring - suggest_key_change() - T054: Circle of fifths modulation - validate_sample_key() - T055: Sample key validation - analyze_spectral_fit() - T057/T062: Spectral role matching FASE 6 - Mastering & QA (8/13 tasks): - calibrate_gain_staging() - T079: Auto gain by bus targets - run_mix_quality_check() - T085: LUFS, peaks, L/R balance - export_stem_mixdown() - T087: 24-bit/44.1kHz stem export New files: - audio_key_compatibility.py (T052) - bus_routing_fix.py (T101-T104) - validation_system_fix.py (T105-T106) Total: 76/110 tasks (69%), 71 MCP tools exposed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
192
AbletonMCP_AI/MCP_Server/full_integration.py
Normal file
192
AbletonMCP_AI/MCP_Server/full_integration.py
Normal file
@@ -0,0 +1,192 @@
|
||||
"""
|
||||
full_integration.py - Integración completa de todas las fases
|
||||
Este módulo conecta todos los nuevos engines con el flujo principal.
|
||||
"""
|
||||
import logging
|
||||
from typing import Dict, Any, List, Optional
|
||||
from pathlib import Path
|
||||
|
||||
# Imports de todos los nuevos módulos
|
||||
from human_feel import HumanFeelEngine
|
||||
from audio_soundscape import SoundscapeEngine, FXEngine, TonalAnalyzer
|
||||
from audio_arrangement import DJArrangementEngine, TransitionEngine
|
||||
from audio_mastering import MasterChain, LoudnessAnalyzer, QASuite, MasteringPreset
|
||||
from self_ai import AutoPrompter, CritiqueEngine, AutoFixEngine
|
||||
|
||||
logger = logging.getLogger("FullIntegration")
|
||||
|
||||
|
||||
class AbletonMCPFullPipeline:
|
||||
"""
|
||||
Pipeline completo que integra todas las fases:
|
||||
1. Auto-prompter (Fase 7)
|
||||
2. Palette selection (Fase 2)
|
||||
3. Arrangement generation (Fase 5)
|
||||
4. Human feel (Fase 3)
|
||||
5. Soundscape/FX (Fase 4)
|
||||
6. Mastering (Fase 6)
|
||||
7. QA validation (Fase 6)
|
||||
8. Critique & Auto-fix (Fase 7)
|
||||
"""
|
||||
|
||||
def __init__(self, seed: int = 42):
|
||||
self.seed = seed
|
||||
self.human_engine = HumanFeelEngine(seed=seed)
|
||||
self.soundscape_engine = SoundscapeEngine()
|
||||
self.fx_engine = FXEngine()
|
||||
self.tonal_analyzer = TonalAnalyzer()
|
||||
self.arrangement_engine = DJArrangementEngine(seed=seed)
|
||||
self.transition_engine = TransitionEngine()
|
||||
self.master_chain = MasterChain()
|
||||
self.loudness_analyzer = LoudnessAnalyzer()
|
||||
self.qa_suite = QASuite()
|
||||
self.auto_prompter = AutoPrompter()
|
||||
self.critique_engine = CritiqueEngine()
|
||||
self.auto_fix_engine = AutoFixEngine()
|
||||
|
||||
def generate_from_vibe(self, vibe_text: str, apply_full_pipeline: bool = True) -> Dict[str, Any]:
|
||||
"""
|
||||
Generación completa desde descripción de vibe.
|
||||
|
||||
Args:
|
||||
vibe_text: Descripción (ej: "dark warehouse techno")
|
||||
apply_full_pipeline: Si aplicar todas las fases
|
||||
|
||||
Returns:
|
||||
Dict con configuración completa del track
|
||||
"""
|
||||
logger.info(f"Starting generation from vibe: '{vibe_text}'")
|
||||
|
||||
# Fase 7: Auto-prompter
|
||||
params = self.auto_prompter.generate_from_vibe(vibe_text)
|
||||
logger.info(f"Detected: genre={params['genre']}, bpm={params['bpm']}, key={params['key']}")
|
||||
|
||||
# Preparar configuración
|
||||
config = {
|
||||
'vibe_params': params,
|
||||
'genre': params['genre'],
|
||||
'bpm': params['bpm'],
|
||||
'key': params['key'],
|
||||
'style': params['style'],
|
||||
'structure_type': params['structure'],
|
||||
'seed': self.seed,
|
||||
}
|
||||
|
||||
if apply_full_pipeline:
|
||||
config = self._apply_full_pipeline(config)
|
||||
|
||||
return config
|
||||
|
||||
def _apply_full_pipeline(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Aplica todas las fases del pipeline."""
|
||||
|
||||
# Fase 5: Generar estructura
|
||||
structure = self.arrangement_engine.generate_structure(config.get('structure_type', 'standard'))
|
||||
config['structure'] = [
|
||||
{'name': s.name, 'kind': s.kind, 'bars': s.bars, 'energy': s.energy}
|
||||
for s in structure
|
||||
]
|
||||
config['dj_friendly'] = self.arrangement_engine.is_dj_friendly(structure)
|
||||
|
||||
# Fase 5: Transiciones
|
||||
transitions = self.transition_engine.generate_all_transitions(structure)
|
||||
config['transitions'] = transitions
|
||||
|
||||
# Fase 4: Soundscape gaps
|
||||
timeline = [{'start': 0, 'end': s.bars * 4, 'kind': s.kind} for s in structure]
|
||||
gaps = self.soundscape_engine.detect_ambience_gaps(timeline)
|
||||
atmos_events = self.soundscape_engine.fill_with_atmos(gaps, config['genre'], config['key'])
|
||||
config['atmos_events'] = atmos_events
|
||||
|
||||
# Fase 4: FX automáticos
|
||||
fx_events = []
|
||||
for section in structure:
|
||||
if section.kind == 'drop':
|
||||
riser = self.fx_engine.auto_riser_before_drop(section.bars * 4, 8)
|
||||
snare_roll = self.fx_engine.auto_snare_roll(section.bars * 4, 4)
|
||||
fx_events.extend([riser, snare_roll])
|
||||
config['fx_events'] = fx_events
|
||||
|
||||
# Fase 6: Master chain
|
||||
preset = MasteringPreset.get_preset('club' if 'techno' in config['genre'] else 'streaming')
|
||||
self.master_chain.set_limiter_ceiling(preset['ceiling'])
|
||||
config['master_chain'] = self.master_chain.get_ableton_device_chain()
|
||||
|
||||
# Fase 3: Configurar human feel
|
||||
config['human_feel'] = {
|
||||
'enabled': True,
|
||||
'timing_variation_ms': 5.0,
|
||||
'velocity_variance': 0.05,
|
||||
'note_skip_prob': 0.02,
|
||||
'groove_style': 'shuffle',
|
||||
'section_dynamics': True,
|
||||
}
|
||||
|
||||
return config
|
||||
|
||||
def critique_and_fix(self, song_data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""
|
||||
Fase 7: Critique loop y auto-fix.
|
||||
|
||||
Args:
|
||||
song_data: Datos de la canción generada
|
||||
|
||||
Returns:
|
||||
Resultado con scores y fixes aplicados
|
||||
"""
|
||||
# Critique
|
||||
critique = self.critique_engine.critique_song(song_data)
|
||||
|
||||
# Auto-fix si hay weaknesses
|
||||
if critique['weaknesses']:
|
||||
fixes = self.auto_fix_engine.auto_fix(critique, song_data)
|
||||
return {
|
||||
'critique': critique,
|
||||
'fixes': fixes,
|
||||
'final_score': fixes['after_score']
|
||||
}
|
||||
|
||||
return {
|
||||
'critique': critique,
|
||||
'fixes': None,
|
||||
'final_score': critique['overall_score']
|
||||
}
|
||||
|
||||
def validate_master(self, audio_data: Any) -> Dict[str, Any]:
|
||||
"""
|
||||
Fase 6: Validación completa del master.
|
||||
|
||||
Args:
|
||||
audio_data: Datos de audio a validar
|
||||
|
||||
Returns:
|
||||
Reporte QA
|
||||
"""
|
||||
return self.qa_suite.run_full_qa(audio_data, {})
|
||||
|
||||
|
||||
# Instancia global
|
||||
_full_pipeline: Optional[AbletonMCPFullPipeline] = None
|
||||
|
||||
|
||||
def get_full_pipeline(seed: int = 42) -> AbletonMCPFullPipeline:
|
||||
"""Obtiene instancia del pipeline completo."""
|
||||
global _full_pipeline
|
||||
if _full_pipeline is None:
|
||||
_full_pipeline = AbletonMCPFullPipeline(seed=seed)
|
||||
return _full_pipeline
|
||||
|
||||
|
||||
def generate_complete_track(vibe_text: str, seed: int = 42) -> Dict[str, Any]:
|
||||
"""
|
||||
Función de conveniencia para generar un track completo.
|
||||
|
||||
Args:
|
||||
vibe_text: Descripción del vibe deseado
|
||||
seed: Seed para reproducibilidad
|
||||
|
||||
Returns:
|
||||
Configuración completa lista para AbletonMCP
|
||||
"""
|
||||
pipeline = get_full_pipeline(seed)
|
||||
return pipeline.generate_from_vibe(vibe_text, apply_full_pipeline=True)
|
||||
Reference in New Issue
Block a user