Initial commit: AbletonMCP-AI complete system
- MCP Server with audio fallback, sample management - Song generator with bus routing - Reference listener and audio resampler - Vector-based sample search - Master chain with limiter and calibration - Fix: Audio fallback now works without M4L - Fix: Full song detection in sample loader Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
244
AbletonMCP_AI/MCP_Server/sample_system_demo.py
Normal file
244
AbletonMCP_AI/MCP_Server/sample_system_demo.py
Normal file
@@ -0,0 +1,244 @@
|
||||
"""
|
||||
Demo del Sistema de Gestión de Samples para AbletonMCP-AI
|
||||
|
||||
Este script demuestra las capacidades del sistema completo de samples.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from sample_manager import get_manager
|
||||
from sample_selector import get_selector
|
||||
from audio_analyzer import analyze_sample, AudioAnalyzer
|
||||
|
||||
|
||||
def demo_analyzer():
|
||||
"""Demostración del analizador de audio"""
|
||||
print("=" * 60)
|
||||
print("DEMO: Audio Analyzer")
|
||||
print("=" * 60)
|
||||
|
||||
AudioAnalyzer(backend='basic')
|
||||
|
||||
# Analizar un archivo de ejemplo
|
||||
test_file = r"C:\Users\ren\embeddings\all_tracks\BBH - Primer Impacto - Kick 1.wav"
|
||||
|
||||
print(f"\nAnalizando: {Path(test_file).name}")
|
||||
print("-" * 40)
|
||||
|
||||
try:
|
||||
result = analyze_sample(test_file)
|
||||
|
||||
print(f"Tipo detectado: {result['sample_type']}")
|
||||
print(f"BPM: {result.get('bpm') or 'No detectado'}")
|
||||
print(f"Key: {result.get('key') or 'No detectado'}")
|
||||
print(f"Duración: {result['duration']:.3f}s")
|
||||
print(f"Es percusivo: {result['is_percussive']}")
|
||||
print(f"Géneros sugeridos: {', '.join(result['suggested_genres'])}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def demo_manager():
|
||||
"""Demostración del gestor de samples"""
|
||||
print("=" * 60)
|
||||
print("DEMO: Sample Manager")
|
||||
print("=" * 60)
|
||||
|
||||
manager = get_manager(r"C:\Users\ren\embeddings\all_tracks")
|
||||
|
||||
# Escanear librería
|
||||
print("\nEscaneando librería...")
|
||||
stats = manager.scan_directory()
|
||||
print(f" Samples procesados: {stats['processed']}")
|
||||
print(f" Nuevos: {stats['added']}")
|
||||
print(f" Total en librería: {stats['total_samples']}")
|
||||
|
||||
# Estadísticas
|
||||
print("\nEstadísticas:")
|
||||
stats = manager.get_stats()
|
||||
print(f" Total: {stats['total_samples']} samples")
|
||||
print(f" Tamaño: {stats['total_size'] / (1024**2):.1f} MB")
|
||||
|
||||
if stats['by_category']:
|
||||
print("\n Por categoría:")
|
||||
for cat, count in sorted(stats['by_category'].items(), key=lambda x: -x[1]):
|
||||
print(f" {cat}: {count}")
|
||||
|
||||
if stats['by_key']:
|
||||
print("\n Por key:")
|
||||
for key, count in sorted(stats['by_key'].items(), key=lambda x: -x[1]):
|
||||
print(f" {key}: {count}")
|
||||
|
||||
# Búsquedas
|
||||
print("\nBúsquedas:")
|
||||
print("-" * 40)
|
||||
|
||||
# Buscar kicks
|
||||
kicks = manager.search(sample_type="kick", limit=3)
|
||||
print(f"\nKicks encontrados: {len(kicks)}")
|
||||
for s in kicks:
|
||||
print(f" - {s.name}")
|
||||
|
||||
# Buscar por key
|
||||
g_sharp = manager.search(key="G#m", limit=3)
|
||||
print(f"\nSamples en G#m: {len(g_sharp)}")
|
||||
for s in g_sharp:
|
||||
print(f" - {s.name} ({s.sample_type})")
|
||||
|
||||
# Buscar por BPM
|
||||
bpm_128 = manager.search(bpm=128, bpm_tolerance=5, limit=3)
|
||||
print(f"\nSamples ~128 BPM: {len(bpm_128)}")
|
||||
for s in bpm_128:
|
||||
key_info = f" [{s.key}]" if s.key else ""
|
||||
print(f" - {s.name}{key_info}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def demo_selector():
|
||||
"""Demostración del selector inteligente"""
|
||||
print("=" * 60)
|
||||
print("DEMO: Sample Selector")
|
||||
print("=" * 60)
|
||||
|
||||
selector = get_selector()
|
||||
|
||||
# Seleccionar para diferentes géneros
|
||||
genres = ['techno', 'house', 'tech-house']
|
||||
|
||||
for genre in genres:
|
||||
print(f"\n{genre.upper()}:")
|
||||
print("-" * 40)
|
||||
|
||||
group = selector.select_for_genre(genre, key='Am', bpm=128)
|
||||
|
||||
print(f" Key: {group.key} | BPM: {group.bpm}")
|
||||
|
||||
# Drum kit
|
||||
kit = group.drums
|
||||
print("\n Drum Kit:")
|
||||
if kit.kick:
|
||||
print(f" Kick: {kit.kick.name}")
|
||||
if kit.snare:
|
||||
print(f" Snare: {kit.snare.name}")
|
||||
if kit.clap:
|
||||
print(f" Clap: {kit.clap.name}")
|
||||
if kit.hat_closed:
|
||||
print(f" Hat: {kit.hat_closed.name}")
|
||||
|
||||
# Mapeo MIDI
|
||||
mapping = selector.get_midi_mapping_for_kit(kit)
|
||||
print("\n Mapeo MIDI:")
|
||||
for note, info in sorted(mapping['notes'].items())[:4]:
|
||||
if info['sample']:
|
||||
print(f" Note {note}: {info['sample'][:40]}...")
|
||||
|
||||
# Bass
|
||||
if group.bass:
|
||||
print(f"\n Bass ({len(group.bass)}):")
|
||||
for s in group.bass[:2]:
|
||||
key_info = f" [{s.key}]" if s.key else ""
|
||||
print(f" - {s.name}{key_info}")
|
||||
|
||||
# Cambio de key
|
||||
print("\n" + "-" * 40)
|
||||
print("Cambios de Key Sugeridos (desde Am):")
|
||||
changes = ['fifth_up', 'fifth_down', 'relative', 'parallel']
|
||||
for change in changes:
|
||||
new_key = selector.suggest_key_change('Am', change)
|
||||
print(f" {change}: {new_key}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def demo_compatibility():
|
||||
"""Demostración de búsqueda de samples compatibles"""
|
||||
print("=" * 60)
|
||||
print("DEMO: Compatibilidad de Samples")
|
||||
print("=" * 60)
|
||||
|
||||
manager = get_manager()
|
||||
selector = get_selector()
|
||||
|
||||
# Encontrar un sample con key para usar de referencia
|
||||
samples_with_key = manager.search(key="G#m", limit=1)
|
||||
|
||||
if samples_with_key:
|
||||
reference = samples_with_key[0]
|
||||
print(f"\nSample de referencia: {reference.name}")
|
||||
print(f" Key: {reference.key} | BPM: {reference.bpm}")
|
||||
|
||||
# Buscar compatibles
|
||||
compatible = selector.find_compatible_samples(reference, max_results=5)
|
||||
|
||||
print("\nSamples compatibles:")
|
||||
print("-" * 40)
|
||||
|
||||
for sample, score in compatible:
|
||||
bar_len = int(score * 20)
|
||||
bar = "█" * bar_len + "░" * (20 - bar_len)
|
||||
print(f" [{bar}] {score:.1%} - {sample.name}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def demo_pack_generation():
|
||||
"""Demostración de generación de packs"""
|
||||
print("=" * 60)
|
||||
print("DEMO: Generación de Sample Packs")
|
||||
print("=" * 60)
|
||||
|
||||
manager = get_manager()
|
||||
|
||||
genres = ['techno', 'house', 'deep-house']
|
||||
|
||||
for genre in genres:
|
||||
print(f"\n{genre.upper()} Pack:")
|
||||
print("-" * 40)
|
||||
|
||||
pack = manager.get_pack_for_genre(genre, key='Am', bpm=128)
|
||||
|
||||
total = 0
|
||||
for category, samples in pack.items():
|
||||
if samples:
|
||||
count = len(samples)
|
||||
total += count
|
||||
print(f" {category}: {count}")
|
||||
|
||||
print(f" Total: {total} samples")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def main():
|
||||
"""Ejecutar todas las demos"""
|
||||
print("\n")
|
||||
print("=" * 60)
|
||||
print(" AbletonMCP-AI Sample System Demo ".center(60))
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
try:
|
||||
demo_analyzer()
|
||||
demo_manager()
|
||||
demo_selector()
|
||||
demo_compatibility()
|
||||
demo_pack_generation()
|
||||
|
||||
print("=" * 60)
|
||||
print("Todas las demos completadas exitosamente!")
|
||||
print("=" * 60)
|
||||
|
||||
except Exception as e:
|
||||
print(f"\nError en demo: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user