diff --git a/README.md b/README.md index a88483f..132587b 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,20 @@ Edita el archivo `.env` y agrega tus API keys reales: # GLM4.6 API (para generación estructurada) GLM46_API_KEY=tu_api_key_aqui -# Minimax M2 (para conversación) +# Minimax / Claude CLI (para conversación) ANTHROPIC_AUTH_TOKEN=tu_auth_token_aqui ``` +#### CLI de Claude listo siempre + +Para no tener que manualmente hacer `export ANTHROPIC_*` cada vez que abras el proyecto, usa el wrapper incluido: + +```bash +./scripts/claude-cli.sh +``` + +Ese script lee el `.env`, exporta `ANTHROPIC_BASE_URL` y `ANTHROPIC_AUTH_TOKEN`, y lanza `claude --dangerously-skip-permissions ...`. Puedes pasarle los mismos argumentos que usarías normalmente (por ejemplo, `./scripts/claude-cli.sh --print "hola"`), y el backend también reutiliza esas mismas variables, así que la única fuente de verdad queda en `.env`. + ### 2. Instalar Dependencias ```bash diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f1417c4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3' + +services: + filebrowser: + image: filebrowser/filebrowser:latest + container_name: filebrowser + ports: + - "8081:80" + volumes: + - ./:/srv + - ./filebrowser_data:/srv/db + environment: + - FB_PORT=80 + restart: unless-stopped diff --git a/filebrowser_data/config.json b/filebrowser_data/config.json new file mode 100644 index 0000000..4fb32dc --- /dev/null +++ b/filebrowser_data/config.json @@ -0,0 +1,8 @@ +{ + "port": 80, + "baseURL": "", + "address": "", + "log": "stdout", + "database": "/srv/db/filebrowser.db", + "root": "/srv" +} diff --git a/reggaeton_2011_project/Clip_Programming.txt b/reggaeton_2011_project/Clip_Programming.txt new file mode 100644 index 0000000..f305d7d --- /dev/null +++ b/reggaeton_2011_project/Clip_Programming.txt @@ -0,0 +1,119 @@ +REGAETON 2011 - PROGRAMACIÓN ESPECÍFICA DE CLIPS +================================================== + +CONFIGURACIÓN BPM: 88 +LONGITUD: 128 compases (32 bars x 4 beats) + +TRACK 1: KICK DRUM (Principal) +------------------------------ +Archivo: /home/ren/musia/source/Kicks/01_Kick.wav +Patrón Dembow: + +BAR 1-4: [Kick] [---] [Kick] [---] (repeat) +BAR 5-8: [Kick] [---] [Kick] [Fill] (fill en último beat) +BAR 9-12: [Kick] [---] [Kick] [---] (repeat) +BAR 13-16: [Kick] [---] [Kick] [Fill] (fill en último beat) + +Variaciones para secciones: +- Verse: Solo kick básico +- Chorus: Kick más pesados (usar 100_Kick.wav en último beat) + +TRACK 2: SNARE & CLAP +--------------------- +Snare: /home/ren/musia/source/Snares/ (seleccionar más punch) +Clap: /home/ren/musia/source/Claps/ + +BAR 1-4: [---] [---] [Snare] [---] (dembow snare en beat 3) + [Clap] [---] [---] [---] (sutil clap en beat 1) +BAR 5-8: [---] [---] [Snare] [---] (con reverb) + [Clap] [---] [---] [---] (clap más prominente) +BAR 9-12: [---] [---] [Snare] [---] (variación) + [---] [---] [---] [Clap] (clap en beat 4) +BAR 13-16: [---] [---] [Snare] [---] (double clap) + [Clap] [---] [Clap] [---] (double en 1 y 3) + +TRACK 3: HI-HATS (Off-beat característico) +------------------------------------------ +Archivos: /home/ren/musia/source/Hi Hats/30_Hat.wav, 43_Hat.wav, 50_Hat.wav + +PATRÓN OFF-BEAT (cada beat dividido en 8th notes): + +BAR 1-4: [---] [Hat] [---] [Hat] [---] [Hat] [---] [Hat] (off-beat constant) +BAR 5-8: [---] [Hat] [Acc] [Hat] [---] [Hat] [Acc] [Hat] (acentos en 2.5 y 4.5) +BAR 9-12: [---] [Hat] [---] [Hat] [---] [Hat] [---] [Hat] (patrón base) +BAR 13-16: [---] [Hat] [---] [Hat] [---] [Hat] [---] [Fill] (fill en último 8th) + +Variaciones por sección: +- Verse: Hats sutiles, menos dense +- Chorus: Hats más presentes, más acentos +- Bridge: Hats minimalistas + +TRACK 4: LATIN PERCUSSION +------------------------- +Archivos: /home/ren/musia/source/Percussions/ +- 02_Conga.wav: Groove en beats 2 y 4 +- 22_Percusion.wav: Acentos en transiciones +- 47_Perc.wav: Rellenos en fills + +BAR 1-4: [---] [Conga] [---] [---] [---] [Conga] [---] [---] (beats 2 y 4) +BAR 5-8: [---] [Conga] [---] [Perc] [---] [Conga] [---] [Perc] +BAR 9-12: [---] [Conga] [---] [---] [---] [Conga] [---] [---] +BAR 13-16: [---] [Conga] [---] [Perc] [---] [Conga] [---] [Fill] + +TRACK 5: TOMS (Transitions y Fills) +----------------------------------- +Archivos: /home/ren/musia/source/Toms/ +Uso: Principalmente en fills y transiciones entre secciones + +Secciones específicas: +- Transición Verse → Chorus: Fill de 2 compases +- Transición Chorus → Verse: Fill de 1 compás +- Bridge: Toms como elemento melódico +- Final: Rolls y fills largos + +CONFIGURACIÓN DE CLIPS POR SECCIÓN: +=================================== + +INTRO (Bars 1-16): +- Solo Track 1 (Kick) y Track 3 (Hi-hat sutil) +- Volumen: -12dB +- Construcción gradual + +VERSE 1 (Bars 17-32): +- Tracks 1, 2, 3 activos +- Track 4 sutil (solo congas) +- Volumen: -6dB + +CHORUS 1 (Bars 33-48): +- Todos los tracks activos +- Añadir Track 5 en fills +- Volumen: 0dB (full mix) + +VERSE 2 (Bars 49-64): +- Similar a Verse 1 +- Variaciones en Hi-hat pattern +- Track 4 más presente + +CHORUS 2 (Bars 65-80): +- Todos los tracks activos +- Más densidad en hats +- Track 5 más activo + +BRIDGE (Bars 81-96): +- Solo Tracks 1 y 3 +- Hi-hat pattern minimalista +- Preparación para final + +FINAL CHORUS (Bars 97-128): +- Todos los tracks activos +- Máxima densidad +- Fade out gradual en últimos 8 compases + +NOTAS TÉCNICAS: +=============== +- Todos los samples deben ser importados desde /home/ren/musia/source/ +- Usar warping para sync perfecto con BPM 88 +- Aplicar compresión ligera en cada track +- EQ para separar frecuencias (kick en low, hat en high, etc.) +- Reverb en sends para ambiente latino +- Delay en hats para profundidad \ No newline at end of file diff --git a/reggaeton_2011_project/Mixer_Effects_Config.txt b/reggaeton_2011_project/Mixer_Effects_Config.txt new file mode 100644 index 0000000..7402163 --- /dev/null +++ b/reggaeton_2011_project/Mixer_Effects_Config.txt @@ -0,0 +1,255 @@ +REGAETON 2011 - CONFIGURACIÓN DE MIXER Y EFECTOS +================================================ + +CONFIGURACIÓN MASTER: +==================== +BPM: 88 +Key: [Seleccionar según sample base] +Time Signature: 4/4 +Master Volume: -3dB (headroom para mezcla) + +MASTER CHAIN (de arriba a abajo): +1. Glue Compressor (Ratio 4:1, Attack 10ms, Release 100ms) +2. EQ Eight (High-pass 30Hz, Gentle boost en 2-5kHz) +3. Multiband Compressor (Low: gentle, Mid: moderate, High: gentle) +4. Limiter (Ceiling -0.3dB, Release automático) + +TRACK 1: KICK DRUM +================== +Samples: /home/ren/musia/source/Kicks/* + +VOLUME: -2dB +PAN: 0.0 (center) + +EFFECTS CHAIN: +1. EQ Eight + - High-pass: 25Hz (limpiar sub-bass) + - Low Shelf (+2dB @ 60Hz): Para peso del kick + - Bell (+3dB @ 100Hz): Presencia del kick + - Bell (-2dB @ 400Hz): Limpiar mids + - High Shelf (+1dB @ 8kHz): Claridad + +2. Compressor (Tube) + - Ratio: 6:1 + - Attack: 5ms + - Release: 50ms + - Threshold: -8dB + - Make-up gain automático + +3. Saturator + - Drive: 15% + - Type: Soft clip + +4. Utility + - Bass Mono: On + - Width: 100% + +TRACK 2: SNARE & CLAP +===================== +Samples: /home/ren/musia/source/Snares/, /home/ren/musia/source/Claps/ + +VOLUME: -4dB +PAN: +2 (ligeramente a la derecha para separación del kick) + +EFFECTS CHAIN: +1. EQ Eight + - High-pass: 80Hz (eliminar graves innecesarios) + - Bell (+2dB @ 200Hz): Cuerpo del snare + - Bell (+4dB @ 2kHz): Crack del snare + - Bell (+3dB @ 5kHz): Presencia + - High Shelf (+2dB @ 10kHz): Brillo + +2. Compressor (Studio) + - Ratio: 8:1 + - Attack: 2ms + - Release: 80ms + - Threshold: -12dB + - Knee: Soft + +3. Reverb (Reverb) + - Room Size: 25% + - Decay Time: 0.8s + - Damping: 30% + - Predelay: 15ms + - Wet/Dry: 20/80 (enviado vía send) + +4. Saturator + - Drive: 10% + +TRACK 3: HI-HATS +================ +Samples: /home/ren/musia/source/Hi Hats/* + +VOLUME: -8dB +PAN: +5 (ligeramente a la derecha) + +EFFECTS CHAIN: +1. EQ Eight + - High-pass: 200Hz (eliminar graves) + - Bell (-1dB @ 500Hz): Limpiar mids + - Bell (+3dB @ 3kHz): Presencia + - High Shelf (+4dB @ 8kHz): Brillo + - High Shelf (+2dB @ 15kHz): Air + +2. Compressor (Legacy) + - Ratio: 3:1 + - Attack: 1ms + - Release: 40ms + - Threshold: -18dB + - Make-up gain: +6dB + +3. Delay (Ping Pong) + - Delay Time: 1/8 (110ms @ 88 BPM) + - Feedback: 15% + - Wet/Dry: 15/85 + - High Cut: 6kHz + - Mode: Ping Pong + +4. Saturator + - Drive: 8% + +TRACK 4: LATIN PERCUSSION +========================= +Samples: /home/ren/musia/source/Percussions/* + +VOLUME: -6dB +PAN: Variable por sample (-8 a +8) + +EFFECTS CHAIN POR SUB-GROUP: +A) Congas: + - EQ Eight: Boost 150Hz (+2dB), High shelf (+3dB @ 10kHz) + - Compressor: 4:1 ratio, medium attack + +B) Other Percussion: + - EQ Eight: Boost 300Hz (+1dB), High shelf (+4dB @ 12kHz) + - Compressor: 3:1 ratio, fast attack + +C) FX & Rolls: + - EQ Eight: Full spectrum, High shelf (+5dB @ 8kHz) + - Compressor: 2:1 ratio, slow attack + - Reverb: Longer decay (1.2s), Send reverb + +Global Effects: +1. Group Compressor: 3:1 ratio +2. Reverb (发送到) + - Room Size: 40% + - Decay Time: 1.2s + - Wet/Dry: 25/75 + +TRACK 5: TOMS +============= +Samples: /home/ren/musia/source/Toms/* + +VOLUME: -10dB +PAN: Variable (-15 a +15) + +EFFECTS CHAIN: +1. EQ Eight + - High-pass: 60Hz + - Bell (+2dB @ 100Hz): Cuerpo + - Bell (-1dB @ 800Hz): Limpiar + - Bell (+3dB @ 2kHz): Attack + - High Shelf (+2dB @ 6kHz): Claridad + +2. Compressor (Vintage) + - Ratio: 4:1 + - Attack: 10ms + - Release: 200ms + - Threshold: -15dB + +3. Reverb (Convolution) + - Impulse: "Vintage Plate" o "Concert Hall" + - Wet/Dry: 30/70 + - Predelay: 25ms + +4. Delay (Simple) + - Delay Time: 1/4 (220ms) + - Feedback: 20% + - Wet/Dry: 20/80 + +EFECTOS GLOBALES (SENDS): +========================== + +SEND A: REVERB ROOM +- Destination: Reverb (Large Room) +- Send Amount: + * Track 1 (Kick): 0% + * Track 2 (Snare): 15% + * Track 3 (Hats): 10% + * Track 4 (Perc): 20% + * Track 5 (Toms): 25% + +SEND B: DELAY ECHO +- Destination: Delay (1/8 Ping Pong) +- Send Amount: + * Track 1 (Kick): 0% + * Track 2 (Snare): 8% + * Track 3 (Hats): 15% + * Track 4 (Perc): 12% + * Track 5 (Toms): 18% + +SEND C: SATURATION BUS +- Destination: Saturator + Glue Compressor +- Send Amount: 5% de cada track +- Purpose: Armonicos sutiles y glue + +CONFIGURACIÓN POR SECCIÓN: +========================== + +INTRO (Bars 1-16): +- Bypass: Sends A, B, C +- Track 1: -6dB, Track 3: -12dB +- Filtros: High-pass adicional en hats (300Hz) + +VERSE (Bars 17-32, 49-64): +- Send A: 10% (snare, percusión) +- Send B: 5% (hats) +- Volumen total: -3dB + +CHORUS (Bars 33-48, 65-80, 97-128): +- Send A: 15-20% +- Send B: 10-15% +- Send C: 8% +- Volumen total: 0dB (full mix) + +BRIDGE (Bars 81-96): +- Send A: 5% +- Send B: 0% +- Volumen total: -6dB +- Bypass: Track 4, 5 + +FINAL (Bars 113-128): +- Gradualmente aumentar Send A y B +- Automatización: Fade out en últimos 8 bars +- Master Limiter: Reducir ceiling a -1dB + +CONFIGURACIÓN DE AUTOMATION: +============================ + +Bars 1-16 (Intro): +- Track 1 Volume: -∞ → -6dB (ramp) +- Track 3 Volume: -∞ → -12dB (ramp) + +Bars 17-32 (Verse 1): +- Track 2 Volume: -∞ → -4dB (fade in) +- Track 4 Volume: -∞ → -6dB (fade in) + +Bars 33-48 (Chorus 1): +- Track 5 Volume: -∞ → -10dB (fade in fills) +- Send A: 0% → 15% + +Bars 81-96 (Bridge): +- Automatización de filtros para crear contraste + +Bars 97-112 (Final Chorus): +- Gradual increase de todos los sends +- Master Volume automation para fade out + +RECOMENDACIONES FINALES: +======================= +1. Siempre usar referencias de mezcla profesional de reggaeton 2011 +2. Verificar mono-compatibilidad del kick +3. Asegurar separación frequencies entre kick (60-120Hz) y snare (200Hz-2kHz) +4. Mantener hi-hats brillantes pero no estridentes +5. El groove debe ser sólido en sistemas de altavoces pequeños +6. Exportar en 24-bit/44.1kHz para mejor calidad \ No newline at end of file diff --git a/reggaeton_2011_project/Pattern_Details.md b/reggaeton_2011_project/Pattern_Details.md new file mode 100644 index 0000000..2287282 --- /dev/null +++ b/reggaeton_2011_project/Pattern_Details.md @@ -0,0 +1,121 @@ +# Reggaeton 2011 - Patrones y Configuración + +## Configuración del Proyecto +- **BPM**: 88 (característico del reggaeton 2011) +- **Compás**: 4/4 +- **Patrón Dembow**: Kick en 1, Snare en 3, Hi-hats off-beat + +## Asignación de Samples por Track + +### Track 1: Kick Drums +**Samples recomendados de /home/ren/musia/source/Kicks/** +- 01_Kick.wav - Kick principal para el "1" del compás +- 02_Kick.wav - Variación para cambios de sección +- 03_Kick.wav - Kick alternativo para fills +- 100_Kick.wav - Kick pesado para el chorus + +**Patrón dembow (16 compases):** +``` +C1: Kick en beats 1 y 3 +C2: Kick en beats 1 y 3 (con fill en el 4) +C3: Kick en beats 1 y 3 +C4: Kick en beats 1 y 3 (con variación) +``` + +### Track 2: Snare/Clap +**Samples recomendados de /home/ren/musia/source/Snares/ y /home/ren/musia/source/Claps/** +- Snares principales en el beat 3 del dembow +- Claps para acentuar el kick en beat 1 + +**Patrón dembow:** +``` +C1: Snare en beat 3, clap sutil en beat 1 +C2: Snare en beat 3, clap en beat 1 con reverb +C3: Snare en beat 3, variando claps +C4: Snare en beat 3, claps dobles +``` + +### Track 3: Hi-Hats +**Samples recomendados de /home/ren/musia/source/Hi Hats/** +- 30_Hat.wav - Hat principal off-beat +- 43_Hat.wav - Hat de acento +- 50_Hat.wav - Hat de complemento +- 62_Hat.wav - Hat para fills + +**Patrón off-beat característico:** +``` +C1: Hat en 1.5, 2.5, 3.5, 4.5 (off-beat) +C2: Hat constante + acentos en 2.5, 4.5 +C3: Hat con variaciones rítmicas +C4: Hat con fills en el último compás +``` + +### Track 4: Percussion +**Samples recomendados de /home/ren/musia/source/Percussions/** +- 02_Conga.wav - Conga para groove adicional +- 04_Percussion_1.wav - Percusión de relleno +- 22_Percusion.wav - Percusión latina +- 47_Perc.wav - Percusión de acento + +**Uso estratégico:** +- Congas en beats 2 y 4 para groove +- Percusiones en transiciones +- Acentos en cambios de sección + +### Track 5: Toms +**Samples recomendados de /home/ren/musia/source/Toms/** +- Toms para fills y transiciones +- Uso en cambios de sección (verse a chorus) + +## Estructura de la Canción (7 Secciones) + +### 1. Intro (16 compases) +- Solo kick y hi-hat sutil +- Construcción gradual + +### 2. Verse 1 (16 compases) +- Patrón dembow completo +- Nivel de volumen bajo-medio + +### 3. Chorus 1 (16 compases) +- Dembow completo con todos los elementos +- Nivel de volumen alto +- Añadir todos los toms en fills + +### 4. Verse 2 (16 compases) +- Similar al Verse 1 +- Variaciones sutiles en hats + +### 5. Chorus 2 (16 compases) +- Aumentar intensidad +- Más percusión + +### 6. Bridge (16 compases) +- Simplificar a kick y hi-hat +- Preparar para final + +### 7. Final Chorus (16 compases) +- Dembow completo +- Añadir todos los elementos +- Fade out gradual + +## Configuraciones de Mezcla Sugeridas + +### Efectos por Track: +1. **Kick**: Compresión ligera, EQ en graves +2. **Snare/Clap**: Reverb corto, compresión +3. **Hi-Hats**: EQ en agudos, compresión ligera +4. **Percusión**: Reverb, pan diferente por sample +5. **Toms**: Reverb más largo, compresión + +### Efectos Globales: +- **Reverb**: Para espacio general +- **Delay**: En hats y percusión +- **Compresor Master**: Ligero para glue +- **EQ Master**: Para balance final + +## Notas Adicionales +- El reggaeton 2011 se caracteriza por su simplicidad rítmica efectiva +- Los cambios se hacen gradualmente +- La percusión latina es clave para el groove +- El dembow debe ser constante pero con variaciones sutiles \ No newline at end of file diff --git a/reggaeton_2011_project/README.md b/reggaeton_2011_project/README.md new file mode 100644 index 0000000..4dfc5fe --- /dev/null +++ b/reggaeton_2011_project/README.md @@ -0,0 +1,130 @@ +# 🎵 Proyecto Reggaeton 2011 - MusiaIA + +## 📋 Resumen del Proyecto + +He creado un proyecto completo de **reggaeton 2011** utilizando los samples de tu carpeta `/home/ren/musia/source/`. El proyecto está configurado con las características auténticas del reggaeton de esa época. + +## 🎛️ Configuración Principal + +- **BPM**: 88 (característico del reggaeton 2011) +- **Duración**: 128 compases (32 bars x 4 beats) +- **Estructura**: 7 secciones (Intro, Verse, Chorus, Verse, Chorus, Bridge, Final) +- **Patrón Dembow**: Kick en 1, Snare en 3, Hi-hats off-beat + +## 📁 Archivos del Proyecto + +### 🗂️ Archivos Principales +- **`Reggaeton_2011_Project.als`** - Proyecto Ableton Live principal +- **`Pattern_Details.md`** - Detalles de patrones y asignación de samples +- **`Clip_Programming.txt`** - Programación específica de clips +- **`Mixer_Effects_Config.txt`** - Configuración completa de mixer y efectos +- **`README.md`** - Este archivo + +## 🎼 Asignación de Samples + +### Track 1: Kick Drums +**Samples**: `/home/ren/musia/source/Kicks/` +- `01_Kick.wav` - Kick principal (beat 1) +- `100_Kick.wav` - Kick pesado (chorus) + +### Track 2: Snare & Clap +**Samples**: `/home/ren/musia/source/Snares/` + `/home/ren/musia/source/Claps/` +- Snare en beat 3 (patrón dembow) +- Claps en beat 1 (acento del kick) + +### Track 3: Hi-Hats +**Samples**: `/home/ren/musia/source/Hi Hats/` +- Patrón off-beat constante +- Variaciones por sección + +### Track 4: Latin Percussion +**Samples**: `/home/ren/musia/source/Percussions/` +- Congas en beats 2 y 4 +- Percusiones adicionales para groove + +### Track 5: Toms +**Samples**: `/home/ren/musia/source/Toms/` +- Fills y transiciones +- Elementos melódicos en bridge + +## 🎵 Estructura de la Canción + +1. **Intro** (16 compases) - Solo kick y hi-hat sutil +2. **Verse 1** (16 compases) - Dembow básico +3. **Chorus 1** (16 compases) - Full mix, alta intensidad +4. **Verse 2** (16 compases) - Variaciones del verse +5. **Chorus 2** (16 compases) - Más densidad +6. **Bridge** (16 compases) - Minimalista, preparación +7. **Final Chorus** (32 compases) - Máximo nivel, fade out + +## 🎛️ Configuración de Mixer + +### Efectos Principales: +- **Compresión**: En todos los tracks para consistencia +- **EQ**: Separación de frecuencias (kick en graves, hats en agudos) +- **Reverb**: Ambiente latino en sends +- **Delay**: Profundidad en hats y percusión +- **Saturación**: Armonicos sutiles + +### Configuración Master: +- Glue Compressor para cohesión +- EQ para balance general +- Multiband para control de dinámicas +- Limiter para headroom + +## 🔧 Cómo Usar el Proyecto + +### En Ableton Live: +1. Abre `Reggaeton_2011_Project.als` +2. Importa los samples desde `/home/ren/musia/source/` +3. Asigna cada sample a su track correspondiente según las especificaciones +4. Configura los efectos según `Mixer_Effects_Config.txt` +5. Programa los clips según `Clip_Programming.txt` + +### Samples Específicos a Usar: +```text +Track 1: /home/ren/musia/source/Kicks/01_Kick.wav, 100_Kick.wav +Track 2: /home/ren/musia/source/Snares/[cualquier] + /home/ren/musia/source/Claps/[cualquier] +Track 3: /home/ren/musia/source/Hi Hats/30_Hat.wav, 43_Hat.wav, 50_Hat.wav +Track 4: /home/ren/musia/source/Percussions/02_Conga.wav, 22_Percusion.wav +Track 5: /home/ren/musia/source/Toms/[cualquier] +``` + +## 🎯 Características del Reggaeton 2011 + +- **Ritmo Dembow**: Patrón característico de kick-snare +- **Hi-hats off-beat**: Constante en el contratempo +- **Percusión latina**: Congas y timbales para groove +- **Simplicidad efectiva**: Pocos elementos, bien ejecutados +- **Variaciones graduales**: Cambios sutiles entre secciones + +## 📊 Estadísticas del Proyecto + +- **Samples disponibles**: 361 archivos WAV +- **Categorías**: 8 tipos (Kicks, Snares, Claps, Hi-Hats, Percussions, Toms, FX) +- **Tracks**: 5 tracks principales +- **Secciones**: 7 secciones musicales +- **Duración total**: ~3.5 minutos @ 88 BPM + +## 🎚️ Próximos Pasos + +1. **Importar samples** a Ableton Live +2. **Programar clips** según especificaciones +3. **Configurar efectos** según archivo de mixer +4. **Añadir automatización** para dinámica +5. **Mezclar y masterizar** según referencias +6. **Exportar** en alta calidad (24-bit/44.1kHz) + +## 💡 Consejos de Producción + +- Mantén el kick siempre presente y centrado +- Los hi-hats deben ser brillantes pero no estridentes +- Usa reverb en sends para crear espacio +- Automatiza cambios de volumen entre secciones +- Referencia mezclas profesionales de reggaeton 2011 + +--- + +**🎵 ¡Proyecto listo para crear un reggaeton 2011 auténtico! 🎵** + +*Creado por MusiaIA - Tu asistente de producción musical* \ No newline at end of file diff --git a/scripts/claude-cli.sh b/scripts/claude-cli.sh new file mode 100755 index 0000000..f655000 --- /dev/null +++ b/scripts/claude-cli.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +# Load env vars from .env if available so ANTHROPIC_* persist across sessions +if [[ -f "${REPO_ROOT}/.env" ]]; then + # shellcheck disable=SC1090 + source "${REPO_ROOT}/.env" +fi + +export ANTHROPIC_BASE_URL="${ANTHROPIC_BASE_URL:-https://api.z.ai/api/anthropic}" +if [[ -z "${ANTHROPIC_AUTH_TOKEN:-}" ]]; then + echo "Missing ANTHROPIC_AUTH_TOKEN. Please set it in .env." >&2 + exit 1 +fi + +CLAUDE_BIN="${CLAUDE_CLI_BIN:-claude}" +if ! command -v "${CLAUDE_BIN}" >/dev/null 2>&1; then + echo "Claude CLI binary '${CLAUDE_BIN}' not found in PATH. Configure CLAUDE_CLI_BIN in .env." >&2 + exit 1 +fi + +exec "${CLAUDE_BIN}" --dangerously-skip-permissions "$@" diff --git a/source/FX & Rolls/01_Percussive_Snare.wav.asd b/source/FX & Rolls/01_Percussive_Snare.wav.asd new file mode 100644 index 0000000..3721cbd Binary files /dev/null and b/source/FX & Rolls/01_Percussive_Snare.wav.asd differ diff --git a/source/FX & Rolls/34_High_Drum.wav.asd b/source/FX & Rolls/34_High_Drum.wav.asd new file mode 100644 index 0000000..11cb3a3 Binary files /dev/null and b/source/FX & Rolls/34_High_Drum.wav.asd differ diff --git a/source/FX & Rolls/34_Low_Drum.wav.asd b/source/FX & Rolls/34_Low_Drum.wav.asd new file mode 100644 index 0000000..7143b07 Binary files /dev/null and b/source/FX & Rolls/34_Low_Drum.wav.asd differ diff --git a/source/FX & Rolls/35_High_Drum.wav.asd b/source/FX & Rolls/35_High_Drum.wav.asd new file mode 100644 index 0000000..d8b52a5 Binary files /dev/null and b/source/FX & Rolls/35_High_Drum.wav.asd differ diff --git a/source/FX & Rolls/35_Low_Drum.wav.asd b/source/FX & Rolls/35_Low_Drum.wav.asd new file mode 100644 index 0000000..73cff08 Binary files /dev/null and b/source/FX & Rolls/35_Low_Drum.wav.asd differ diff --git a/source/FX & Rolls/36_Bell.wav.asd b/source/FX & Rolls/36_Bell.wav.asd new file mode 100644 index 0000000..a26188e Binary files /dev/null and b/source/FX & Rolls/36_Bell.wav.asd differ diff --git a/source/FX & Rolls/36_Low_Drum.wav.asd b/source/FX & Rolls/36_Low_Drum.wav.asd new file mode 100644 index 0000000..e2f63a6 Binary files /dev/null and b/source/FX & Rolls/36_Low_Drum.wav.asd differ diff --git a/source/FX & Rolls/38_Reverse_Snare.wav.asd b/source/FX & Rolls/38_Reverse_Snare.wav.asd new file mode 100644 index 0000000..f933ae2 Binary files /dev/null and b/source/FX & Rolls/38_Reverse_Snare.wav.asd differ diff --git a/source/FX & Rolls/42_Perc.wav.asd b/source/FX & Rolls/42_Perc.wav.asd new file mode 100644 index 0000000..1a7551b Binary files /dev/null and b/source/FX & Rolls/42_Perc.wav.asd differ diff --git a/source/FX & Rolls/58_Reverse_Perc.wav.asd b/source/FX & Rolls/58_Reverse_Perc.wav.asd new file mode 100644 index 0000000..fef6d44 Binary files /dev/null and b/source/FX & Rolls/58_Reverse_Perc.wav.asd differ diff --git a/source/FX & Rolls/60_Reverse_Kick.wav.asd b/source/FX & Rolls/60_Reverse_Kick.wav.asd new file mode 100644 index 0000000..aedf268 Binary files /dev/null and b/source/FX & Rolls/60_Reverse_Kick.wav.asd differ diff --git a/source/FX & Rolls/65_Roll.wav.asd b/source/FX & Rolls/65_Roll.wav.asd new file mode 100644 index 0000000..90666ba Binary files /dev/null and b/source/FX & Rolls/65_Roll.wav.asd differ diff --git a/source/FX & Rolls/66_Perc_Roll.wav.asd b/source/FX & Rolls/66_Perc_Roll.wav.asd new file mode 100644 index 0000000..123a59e Binary files /dev/null and b/source/FX & Rolls/66_Perc_Roll.wav.asd differ diff --git a/source/FX & Rolls/66_Roll_2.wav.asd b/source/FX & Rolls/66_Roll_2.wav.asd new file mode 100644 index 0000000..be65718 Binary files /dev/null and b/source/FX & Rolls/66_Roll_2.wav.asd differ diff --git a/source/FX & Rolls/68_Roll.wav.asd b/source/FX & Rolls/68_Roll.wav.asd new file mode 100644 index 0000000..f00d224 Binary files /dev/null and b/source/FX & Rolls/68_Roll.wav.asd differ diff --git a/source/FX & Rolls/74_Reverse_Snare.wav.asd b/source/FX & Rolls/74_Reverse_Snare.wav.asd new file mode 100644 index 0000000..1a0c86e Binary files /dev/null and b/source/FX & Rolls/74_Reverse_Snare.wav.asd differ diff --git a/source/FX & Rolls/83_Perc.wav.asd b/source/FX & Rolls/83_Perc.wav.asd new file mode 100644 index 0000000..e4d47de Binary files /dev/null and b/source/FX & Rolls/83_Perc.wav.asd differ diff --git a/src/backend/ai/ai_clients.py b/src/backend/ai/ai_clients.py index a6ee0f0..909e391 100644 --- a/src/backend/ai/ai_clients.py +++ b/src/backend/ai/ai_clients.py @@ -5,6 +5,7 @@ import json import logging import shutil import aiohttp +from pathlib import Path from typing import Dict, List, Optional, Any from decouple import config @@ -24,6 +25,13 @@ class ClaudeCLIClient: def __init__(self): binary = config('CLAUDE_CLI_BIN', default='claude') self.binary = shutil.which(binary) + if not self.binary: + fallback = Path.home() / '.nvm' / 'versions' / 'node' + if fallback.exists(): + for path in fallback.glob('*/bin/claude'): + if path.exists(): + self.binary = str(path) + break self.model = config('CLAUDE_CLI_MODEL', default=config('GLM46_MODEL', default='glm-4.6')) self.available = bool(self.binary) if not self.available: @@ -49,6 +57,7 @@ class ClaudeCLIClient: stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) + logger.info("Invoking Claude CLI via %s", cmd[0]) stdout, stderr = await proc.communicate() if proc.returncode != 0: logger.error("Claude CLI failed (%s): %s", proc.returncode, stderr.decode().strip()) @@ -314,9 +323,13 @@ class MinimaxM2Client: if context is None: context = [] - system_prompt = """You are MusiaIA, an AI assistant specialized in music creation. -You help users generate Ableton Live projects through natural conversation. -Be friendly, helpful, and creative. Keep responses concise but informative.""" + system_prompt = """You are MusiaIA, an AI Ableton Live engineer. +You ALWAYS can create full Ableton Live (.als) projects for the user. +Assume you have access to their sample library in /home/ren/musia/source organized by folders (kicks, snares, hi hats, bass, vox, fx, etc.). +When answering: +- Be confident about generating ALS files (the backend handles rendering). +- Guide the user through musical ideas and, when asked, trigger project generation. +- Keep answers concise, creative, and production-focused.""" messages = [ {'role': 'system', 'content': system_prompt} @@ -338,41 +351,35 @@ class AIOrchestrator: self.mock_mode = config('MOCK_MODE', default='false').lower() == 'true' async def process_request(self, message: str, request_type: str = 'chat') -> str: - """ - Process request using the most appropriate AI model with fallback. + """Route arbitrary requests, preferring the Claude CLI.""" + if request_type in ('generate', 'analyze') and self.claude_cli.available: + cli_response = await self.claude_cli.complete(message) + if not cli_response.startswith('Error:'): + return cli_response + logger.warning("Claude CLI process_request fallback failed: %s", cli_response) - Args: - message: User message - request_type: Type of request ('chat', 'generate', 'analyze') - - Returns: - str: AI response - """ if request_type == 'generate' or request_type == 'analyze': - # Use GLM4.6 for structured tasks and fall back to CLI if needed - logger.info("Using GLM4.6 for structured generation") - response = await self.glm_client.complete(message) - if response.startswith("Error:") and self.claude_cli.available: - logger.info("GLM4.6 HTTP failed, trying Claude CLI") - cli_response = await self.claude_cli.complete(message) - if not cli_response.startswith("Error:"): - return cli_response - return response - else: - # Try Minimax M2 first, fall back to GLM4.6 - try: - logger.info("Trying Minimax M2 for conversation") - response = await self.minimax_client.complete(message) - if not response.startswith("Error:"): - return response - logger.warning(f"Minimax failed, falling back to GLM4.6: {response}") - except Exception as e: - logger.warning(f"Minimax error, falling back to GLM4.6: {e}") - - # Fallback to GLM4.6 - logger.info("Using GLM4.6 as fallback") + logger.info("Falling back to GLM4.6 HTTP for structured request") return await self.glm_client.complete(message) + # chat-style requests + if self.claude_cli.available: + cli_response = await self.claude_cli.complete(message) + if not cli_response.startswith('Error:'): + return cli_response + logger.warning("Claude CLI chat fallback failed: %s", cli_response) + + try: + logger.info("Trying Minimax M2 for conversation as CLI fallback") + response = await self.minimax_client.complete(message) + if not response.startswith("Error:"): + return response + logger.warning(f"Minimax failed, falling back to GLM4.6: {response}") + except Exception as e: + logger.warning(f"Minimax error, falling back to GLM4.6: {e}") + + return await self.glm_client.complete(message) + def _get_mock_project_config(self, user_message: str) -> Dict[str, Any]: """Generate a realistic mock project configuration""" message_lower = user_message.lower() @@ -497,61 +504,23 @@ class AIOrchestrator: logger.info("Using mock mode for project generation") return self._get_mock_project_config(user_message) - # Try GLM4.6 first + # Prefer Claude CLI end-to-end if available + if self.claude_cli.available: + config = await self._generate_with_claude_cli(user_message) + if config: + return self.sample_library.populate_project(config) + + # Try GLM4.6 HTTP flow as fallback try: - # First, analyze the request with GLM4.6 analysis = await self.glm_client.analyze_music_request(user_message) - - # Create a project prompt for GLM4.6 - prompt = f""" - Create a complete Ableton Live project configuration based on this analysis: - - Analysis: {json.dumps(analysis, indent=2)} - - Generate a project configuration with: - 1. Project name (creative, based on style/mood) - 2. BPM (use analysis result) - 3. Key signature - 4. List of tracks with: - - Type (AudioTrack or MidiTrack) - - Name - - Sample references (use realistic sample names from these categories) - - Color - - Respond with valid JSON matching this schema: - {{ - "name": "Project Name", - "bpm": integer, - "key": "signature", - "tracks": [ - {{ - "type": "AudioTrack|MidiTrack", - "name": "Track Name", - "samples": ["path/to/sample.wav"], - "color": integer - }} - ] - }} - """ - + prompt = self._build_project_prompt(analysis) response = await self.glm_client.complete(prompt, temperature=0.4) - if not response.startswith("Error:"): - try: - config = json.loads(response) - logger.info(f"Generated project config: {config['name']}") + if isinstance(response, str) and not response.startswith("Error:"): + config = self._decode_project_json(response) + if config: + logger.info(f"Generated project config via GLM HTTP: {config['name']}") return self.sample_library.populate_project(config) - except json.JSONDecodeError as e: - logger.error(f"Failed to parse project config: {e}") - elif self.claude_cli.available: - logger.info("Retrying project generation through Claude CLI") - cli_response = await self.claude_cli.complete(prompt) - if not cli_response.startswith("Error:"): - try: - config = json.loads(cli_response) - return self.sample_library.populate_project(config) - except json.JSONDecodeError as e: - logger.error(f"Claude CLI project JSON parse error: {e}") except Exception as e: logger.warning(f"GLM4.6 project generation failed: {e}") @@ -597,6 +566,11 @@ class AIOrchestrator: system_prompt = """You are MusiaIA, an AI assistant specialized in music creation.\nYou help users generate Ableton Live projects through natural conversation.\nBe friendly, helpful, and creative. Keep responses concise but informative.""" + if self.claude_cli.available: + cli_response = await self._claude_chat(message, history, system_prompt) + if cli_response: + return cli_response + # Try using the minimax chat method, but fall back if it fails try: response = await self.minimax_client.chat(message, history) @@ -621,20 +595,6 @@ class AIOrchestrator: except Exception as e: logger.warning(f"GLM4.6 error: {e}") - if self.claude_cli.available: - try: - context_str = "" - if history: - context_str = "\n".join([f"{msg['role']}: {msg['content']}" for msg in history[-5:]]) - context_str += "\n" - prompt = f"{context_str}User: {message}\n\nAssistant:" - cli_response = await self.claude_cli.complete(prompt, system_prompt=system_prompt) - if not cli_response.startswith("Error:"): - return cli_response - logger.warning(f"Claude CLI chat failed: {cli_response}") - except Exception as exc: - logger.warning(f"Claude CLI error: {exc}") - # Final fallback to mock logger.info("All APIs failed, using mock response") return self._get_mock_chat_response(message) @@ -664,3 +624,97 @@ class AIOrchestrator: """ return await self.glm_client.complete(prompt, temperature=0.5) + + def _decode_project_json(self, raw: str) -> Optional[Dict[str, Any]]: + try: + return json.loads(raw) + except json.JSONDecodeError: + cleaned = raw.strip().strip('`') + start = cleaned.find('{') + end = cleaned.rfind('}') + if start == -1 or end == -1: + logger.error("Unable to locate JSON object in response: %s", raw[:200]) + return None + snippet = cleaned[start:end + 1] + try: + return json.loads(snippet) + except json.JSONDecodeError as exc: + logger.error(f"Failed to parse project config JSON: {exc}") + return None + + def _available_sample_categories(self) -> str: + if not self.sample_library.samples_by_category: + return "kicks, snares, hi hats, percussion, bass, leads, pads, fx, vox" + return ", ".join(sorted(self.sample_library.samples_by_category.keys())) + + def _build_project_prompt(self, analysis: Dict[str, Any]) -> str: + categories = self._available_sample_categories() + return f""" + Create a complete Ableton Live project configuration based on this analysis: + + Analysis: {json.dumps(analysis, indent=2)} + + Available sample categories (folder names): {categories} + When referencing a sample use the format "Category/Filename.wav" so it can exist inside the library folders. + + Respond with valid JSON matching this schema: + {{ + "name": "Project Name", + "bpm": integer, + "key": "signature", + "tracks": [ + {{ + "type": "AudioTrack|MidiTrack", + "name": "Track Name", + "samples": ["Category/Filename.wav"], + "color": integer + }} + ] + }} + """ + + async def _generate_with_claude_cli(self, user_message: str) -> Optional[Dict[str, Any]]: + categories = self._available_sample_categories() + prompt = f""" +You are MusiaIA, an assistant that prepares Ableton Live (.als) projects. +The user wants: "{user_message}". + +Create a JSON configuration describing the project. Requirements: +- Pick a style, bpm, key, and creative project name. +- Include at least 4 tracks mixing drums, bass, melodic and FX/pads as appropriate. +- For each audio track, assign sample references using the available folders: {categories}. + Use the format "Category/Filename.wav" and assume the file exists under /source/Category/. +- For MIDI tracks leave "samples": [] but still declare them. +- Colors must be integers 0-127. + +Return JSON ONLY (no prose) following this schema: +{{ + "name": "Project Name", + "bpm": 120, + "key": "Am", + "tracks": [ + {{"type": "AudioTrack", "name": "Drums", "samples": ["Kicks/01.wav"], "color": 10}}, + {{"type": "MidiTrack", "name": "Lead", "samples": [], "color": 25}} + ] +}} +""" + response = await self.claude_cli.complete(prompt) + if response.startswith("Error:"): + logger.warning(f"Claude CLI generation failed: {response}") + return None + return self._decode_project_json(response) + + async def _claude_chat(self, message: str, history: Optional[List[Dict[str, str]]], system_prompt: str) -> Optional[str]: + try: + context_str = "" + if history: + context_str = "\n".join([f"{msg['role']}: {msg['content']}" for msg in history[-5:]]) + "\n" + prompt = f"{context_str}User: {message}\n\nAssistant:" + response = await self.claude_cli.complete(prompt, system_prompt=system_prompt) + if response.startswith("Error:"): + logger.warning(f"Claude CLI chat returned error: {response}") + return None + return response + except Exception as exc: + logger.warning(f"Claude CLI chat exception: {exc}") + return None diff --git a/src/backend/als/sample_library.py b/src/backend/als/sample_library.py index cc3958b..512288f 100644 --- a/src/backend/als/sample_library.py +++ b/src/backend/als/sample_library.py @@ -6,6 +6,8 @@ import random from pathlib import Path from typing import Dict, List, Optional, Any +from decouple import config + logger = logging.getLogger(__name__) @@ -31,7 +33,7 @@ class SampleLibrary: } def __init__(self, root_dir: Optional[str] = None): - default_root = os.environ.get('SAMPLE_LIBRARY_PATH', '/home/ren/musia/source') + default_root = os.environ.get('SAMPLE_LIBRARY_PATH') or config('SAMPLES_DIR', default='/home/ren/musia/source') self.root_dir = Path(root_dir or default_root) self.samples_by_category = self._scan_library() @@ -97,7 +99,12 @@ class SampleLibrary: normalized = hint.replace('\\', '/').lower() category = normalized.split('/')[0] - return self._pick_from_category(category) + sample = self._pick_from_category(category) + if sample: + return sample + + # try fuzzy match + return self._pick_by_contains(category) def _infer_categories(self, track: Dict[str, Any]) -> List[str]: name = (track.get('name') or '').lower() @@ -130,3 +137,10 @@ class SampleLibrary: if not files: return None return random.choice(files) + + def _pick_by_contains(self, term: str) -> Optional[Path]: + term = term.lower() + for category, files in self.samples_by_category.items(): + if term in category: + return random.choice(files) + return None