feat: Implement senior audio injection with 5 fallback methods
- Add _cmd_create_arrangement_audio_pattern with 5-method fallback chain - Method 1: track.insert_arrangement_clip() [Live 12+] - Method 2: track.create_audio_clip() [Live 11+] - Method 3: arrangement_clips.add_new_clip() [Live 12+] - Method 4: Session->duplicate_clip_to_arrangement [Legacy] - Method 5: Session->Recording [Universal] - Add _cmd_duplicate_clip_to_arrangement for session-to-arrangement workflow - Update skills documentation - Verified: 3 clips created at positions [0, 4, 8] in Arrangement View Closes: Audio injection in Arrangement View
This commit is contained in:
190
docs/sprint_1_libreria_analisis_espectral.md
Normal file
190
docs/sprint_1_libreria_analisis_espectral.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# SPRINT 1 - Análisis Espectral de Librería + Embeddings
|
||||
|
||||
> **Date**: 2026-04-11
|
||||
> **Assigned**: Kimi K2
|
||||
> **Reviewed by**: Qwen (después de completar)
|
||||
> **Priority**: CRÍTICA - Base para generación inteligente
|
||||
|
||||
---
|
||||
|
||||
## OBJETIVO
|
||||
|
||||
Analizar TODOS los samples de `libreria/reggaeton/` (509 samples) con técnicas de análisis de audio avanzado para poder:
|
||||
1. Encontrar samples similares entre sí
|
||||
2. Comparar contra `reggaeton_ejemplo.mp3` como referencia
|
||||
3. Generar canciones que suenen similar a la biblioteca del usuario
|
||||
|
||||
---
|
||||
|
||||
## ARCHIVOS A CREAR
|
||||
|
||||
### 1. `libreria_analyzer.py`
|
||||
**Ubicación**: `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\mcp_server\engines\libreria_analyzer.py`
|
||||
|
||||
**Funcionalidad**:
|
||||
- Escanea recursivamente `libreria/reggaeton/` buscando TODOS los .wav, .mp3, .aif, .flac
|
||||
- Para CADA sample extraer:
|
||||
- **BPM** (tempo detection via onset detection)
|
||||
- **Key** (key detection via chromagram)
|
||||
- **RMS** (nivel de energía/promedio)
|
||||
- **Spectral Centroid** (brillo del sample)
|
||||
- **Spectral Rolloff** (frecuencia de corte)
|
||||
- **Zero Crossing Rate** (percutivo vs sostenido)
|
||||
- **MFCCs** (13 coeficientes - timbre/fingerprint)
|
||||
- **Onset Strength** (qué tan rítmico/percutivo es)
|
||||
- **Duration** (duración en segundos)
|
||||
- **Sample Rate**
|
||||
- **Channels** (mono/stereo)
|
||||
- Guardar todo en cache: `libreria/reggaeton/.features_cache.json`
|
||||
- Formato del JSON:
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"total_samples": 509,
|
||||
"scan_date": "2026-04-11T...",
|
||||
"samples": {
|
||||
"C:/.../libreria/reggaeton/kick/kick_808.wav": {
|
||||
"name": "kick_808.wav",
|
||||
"pack": "kick",
|
||||
"bpm": 0,
|
||||
"key": "",
|
||||
"rms": -12.5,
|
||||
"spectral_centroid": 2500.0,
|
||||
"spectral_rolloff": 8000.0,
|
||||
"zero_crossing_rate": 0.15,
|
||||
"mfccs": [0.5, -0.3, 0.1, ...],
|
||||
"onset_strength": 0.85,
|
||||
"duration": 0.5,
|
||||
"sample_rate": 44100,
|
||||
"channels": 1,
|
||||
"role": "kick"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. `embedding_engine.py`
|
||||
**Ubicación**: `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\mcp_server\engines\embedding_engine.py`
|
||||
|
||||
**Funcionalidad**:
|
||||
- Crear embedding vectorial para cada sample (numpy array de ~20 dimensiones)
|
||||
- El embedding combina: BPM, Key, RMS, Spectral Centroid, Spectral Rolloff, ZCR, MFCCs(13), Onset Strength, Duration
|
||||
- Normalizar todos los embeddings (min-max scaling) para que sean comparables
|
||||
- Guardar en: `libreria/reggaeton/.embeddings_index.json` (como arrays serializados)
|
||||
- Función `find_similar(sample_path, top_n=10)` → retorna samples más similares por distancia coseno o euclidiana
|
||||
- Función `find_by_audio_reference(audio_file_path, top_n=20)` → analiza un archivo de audio completo y encuentra los samples más similares
|
||||
|
||||
### 3. `reference_matcher.py`
|
||||
**Ubicación**: `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\mcp_server\engines\reference_matcher.py`
|
||||
|
||||
**Funcionalidad**:
|
||||
- Analizar `libreria/reggaeton_ejemplo.mp3` como track de referencia
|
||||
- Extraer su fingerprint espectral completo (BPM, Key, energy curve, timbre promedio)
|
||||
- Comparar TODA la librería contra esta referencia
|
||||
- Generar ranking: qué samples son más similares al estilo del usuario
|
||||
- Crear "perfil de sonido" del usuario:
|
||||
- BPM preferido
|
||||
- Key preferida
|
||||
- Timbre promedio (MFCCs medios)
|
||||
- Energy curve
|
||||
- Roles de samples más usados (kick, snare, etc.)
|
||||
- Guardar en: `libreria/reggaeton/.user_sound_profile.json`
|
||||
|
||||
---
|
||||
|
||||
## DETALLES DE IMPLEMENTACIÓN
|
||||
|
||||
### Librerías a usar
|
||||
```python
|
||||
import numpy as np
|
||||
import librosa # Análisis espectral principal
|
||||
import librosa.feature # MFCCs, spectral centroid, etc.
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
```
|
||||
|
||||
Si librosa NO está disponible, usar fallback con:
|
||||
- `scipy.io.wavfile` para leer WAVs
|
||||
- Estimación de BPM por onset detection simple
|
||||
- Sin MFCCs (usar spectral centroid básico)
|
||||
|
||||
### Estructura de la librería
|
||||
```
|
||||
libreria/reggaeton/
|
||||
├── reggaeton_ejemplo.mp3 ← Referencia PRINCIPAL
|
||||
├── kick/
|
||||
├── snare/
|
||||
├── bass/
|
||||
├── fx/
|
||||
├── drumloops/
|
||||
├── hi-hat (para percs normalmente)/
|
||||
├── oneshots/
|
||||
├── perc loop/
|
||||
├── reggaeton 3/
|
||||
├── SentimientoLatino2025/
|
||||
├── sounds presets/
|
||||
├── (extra)/
|
||||
└── flp/
|
||||
```
|
||||
|
||||
### Detección de rol por carpeta
|
||||
El rol de cada sample se infiere de la carpeta donde está:
|
||||
- `kick/` → "kick"
|
||||
- `snare/` → "snare"
|
||||
- `bass/` → "bass"
|
||||
- `fx/` → "fx"
|
||||
- `drumloops/` → "drum_loop"
|
||||
- `hi-hat*/` → "hat_closed"
|
||||
- `oneshots/` → "oneshot"
|
||||
- `perc loop/` → "perc_loop"
|
||||
- `reggaeton 3/` → "synth" (default)
|
||||
- `SentimientoLatino2025/` → "multi" (pack completo)
|
||||
|
||||
---
|
||||
|
||||
## ARCHIVOS A MODIFICAR
|
||||
|
||||
### `sample_selector.py`
|
||||
Agregar método `select_by_similarity(reference_path, top_n=10)` que:
|
||||
1. Usa `embedding_engine.find_similar()` para encontrar samples similares
|
||||
2. Retorna un InstrumentGroup con los samples más parecidos a la referencia
|
||||
|
||||
---
|
||||
|
||||
## ARCHIVOS DE SALIDA GENERADOS
|
||||
|
||||
| Archivo | Contenido |
|
||||
|---------|-----------|
|
||||
| `libreria/reggaeton/.features_cache.json` | Features de los 509 samples |
|
||||
| `libreria/reggaeton/.embeddings_index.json` | Embeddings vectoriales normalizados |
|
||||
| `libreria/reggaeton/.user_sound_profile.json` | Perfil de sonido del usuario |
|
||||
|
||||
---
|
||||
|
||||
## RESTRICCIONES
|
||||
|
||||
1. **NO MODIFICAR** ningún sample .wav/.mp3 - solo lectura
|
||||
2. **NO ELIMINAR** nada de `libreria/`
|
||||
3. El análisis puede tardar varios minutos (509 samples) - mostrar progreso
|
||||
4. Usar caché: si `.features_cache.json` existe y es reciente, no re-analizar
|
||||
5. Todos los paths en los JSON deben ser absolutos (Windows)
|
||||
6. Compilar cada archivo después de crear: `python -m py_compile "<path>"`
|
||||
|
||||
---
|
||||
|
||||
## VERIFICACIÓN (Qwen hará esto después)
|
||||
|
||||
```powershell
|
||||
# Compilar
|
||||
python -m py_compile "C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\mcp_server\engines\libreria_analyzer.py"
|
||||
python -m py_compile "C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\mcp_server\engines\embedding_engine.py"
|
||||
python -m py_compile "C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\mcp_server\engines\reference_matcher.py"
|
||||
|
||||
# Test rápido
|
||||
python -c "from engines.libreria_analyzer import LibreriaAnalyzer; a = LibreriaAnalyzer(); print(f'Scanned {len(a.features)} samples')"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Cuando termines, avisale a Qwen para que revise, compile y cree el Sprint 2.**
|
||||
Reference in New Issue
Block a user