chore: Add comprehensive sample library and production resources
📁 New Additions: - Docker Compose configuration for easy deployment - Sample Library: 20+ high-quality audio samples (FX & Rolls) - Project Example: Complete reggaeton_2011_project with documentation * Clip programming details * Mixer effects configuration * Pattern details and README - Scripts: Claude CLI integration script - File Browser: Configuration for easy file management 📝 Updated Files: - README.md: Enhanced documentation - ai_clients.py: Further improvements to AI orchestration - sample_library.py: Enhanced sample selection logic 🎵 Sample Library: - FX & Rolls collection with various percussion elements - Reverse snares, kicks, rolls, bells, and percussion - All samples in .asd format (Ableton sample analysis data) This adds substantial production-ready resources to MusiaIA, making it much more capable of generating diverse music projects! Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
12
README.md
12
README.md
@@ -41,10 +41,20 @@ Edita el archivo `.env` y agrega tus API keys reales:
|
|||||||
# GLM4.6 API (para generación estructurada)
|
# GLM4.6 API (para generación estructurada)
|
||||||
GLM46_API_KEY=tu_api_key_aqui
|
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
|
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
|
### 2. Instalar Dependencias
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
14
docker-compose.yml
Normal file
14
docker-compose.yml
Normal file
@@ -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
|
||||||
8
filebrowser_data/config.json
Normal file
8
filebrowser_data/config.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"port": 80,
|
||||||
|
"baseURL": "",
|
||||||
|
"address": "",
|
||||||
|
"log": "stdout",
|
||||||
|
"database": "/srv/db/filebrowser.db",
|
||||||
|
"root": "/srv"
|
||||||
|
}
|
||||||
119
reggaeton_2011_project/Clip_Programming.txt
Normal file
119
reggaeton_2011_project/Clip_Programming.txt
Normal file
@@ -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
|
||||||
255
reggaeton_2011_project/Mixer_Effects_Config.txt
Normal file
255
reggaeton_2011_project/Mixer_Effects_Config.txt
Normal file
@@ -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
|
||||||
121
reggaeton_2011_project/Pattern_Details.md
Normal file
121
reggaeton_2011_project/Pattern_Details.md
Normal file
@@ -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
|
||||||
130
reggaeton_2011_project/README.md
Normal file
130
reggaeton_2011_project/README.md
Normal file
@@ -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*
|
||||||
24
scripts/claude-cli.sh
Executable file
24
scripts/claude-cli.sh
Executable file
@@ -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 "$@"
|
||||||
BIN
source/FX & Rolls/01_Percussive_Snare.wav.asd
Normal file
BIN
source/FX & Rolls/01_Percussive_Snare.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/34_High_Drum.wav.asd
Normal file
BIN
source/FX & Rolls/34_High_Drum.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/34_Low_Drum.wav.asd
Normal file
BIN
source/FX & Rolls/34_Low_Drum.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/35_High_Drum.wav.asd
Normal file
BIN
source/FX & Rolls/35_High_Drum.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/35_Low_Drum.wav.asd
Normal file
BIN
source/FX & Rolls/35_Low_Drum.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/36_Bell.wav.asd
Normal file
BIN
source/FX & Rolls/36_Bell.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/36_Low_Drum.wav.asd
Normal file
BIN
source/FX & Rolls/36_Low_Drum.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/38_Reverse_Snare.wav.asd
Normal file
BIN
source/FX & Rolls/38_Reverse_Snare.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/42_Perc.wav.asd
Normal file
BIN
source/FX & Rolls/42_Perc.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/58_Reverse_Perc.wav.asd
Normal file
BIN
source/FX & Rolls/58_Reverse_Perc.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/60_Reverse_Kick.wav.asd
Normal file
BIN
source/FX & Rolls/60_Reverse_Kick.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/65_Roll.wav.asd
Normal file
BIN
source/FX & Rolls/65_Roll.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/66_Perc_Roll.wav.asd
Normal file
BIN
source/FX & Rolls/66_Perc_Roll.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/66_Roll_2.wav.asd
Normal file
BIN
source/FX & Rolls/66_Roll_2.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/68_Roll.wav.asd
Normal file
BIN
source/FX & Rolls/68_Roll.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/74_Reverse_Snare.wav.asd
Normal file
BIN
source/FX & Rolls/74_Reverse_Snare.wav.asd
Normal file
Binary file not shown.
BIN
source/FX & Rolls/83_Perc.wav.asd
Normal file
BIN
source/FX & Rolls/83_Perc.wav.asd
Normal file
Binary file not shown.
@@ -5,6 +5,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import shutil
|
import shutil
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Any
|
from typing import Dict, List, Optional, Any
|
||||||
from decouple import config
|
from decouple import config
|
||||||
|
|
||||||
@@ -24,6 +25,13 @@ class ClaudeCLIClient:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
binary = config('CLAUDE_CLI_BIN', default='claude')
|
binary = config('CLAUDE_CLI_BIN', default='claude')
|
||||||
self.binary = shutil.which(binary)
|
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.model = config('CLAUDE_CLI_MODEL', default=config('GLM46_MODEL', default='glm-4.6'))
|
||||||
self.available = bool(self.binary)
|
self.available = bool(self.binary)
|
||||||
if not self.available:
|
if not self.available:
|
||||||
@@ -49,6 +57,7 @@ class ClaudeCLIClient:
|
|||||||
stdout=asyncio.subprocess.PIPE,
|
stdout=asyncio.subprocess.PIPE,
|
||||||
stderr=asyncio.subprocess.PIPE,
|
stderr=asyncio.subprocess.PIPE,
|
||||||
)
|
)
|
||||||
|
logger.info("Invoking Claude CLI via %s", cmd[0])
|
||||||
stdout, stderr = await proc.communicate()
|
stdout, stderr = await proc.communicate()
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
logger.error("Claude CLI failed (%s): %s", proc.returncode, stderr.decode().strip())
|
logger.error("Claude CLI failed (%s): %s", proc.returncode, stderr.decode().strip())
|
||||||
@@ -314,9 +323,13 @@ class MinimaxM2Client:
|
|||||||
if context is None:
|
if context is None:
|
||||||
context = []
|
context = []
|
||||||
|
|
||||||
system_prompt = """You are MusiaIA, an AI assistant specialized in music creation.
|
system_prompt = """You are MusiaIA, an AI Ableton Live engineer.
|
||||||
You help users generate Ableton Live projects through natural conversation.
|
You ALWAYS can create full Ableton Live (.als) projects for the user.
|
||||||
Be friendly, helpful, and creative. Keep responses concise but informative."""
|
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 = [
|
messages = [
|
||||||
{'role': 'system', 'content': system_prompt}
|
{'role': 'system', 'content': system_prompt}
|
||||||
@@ -338,41 +351,35 @@ class AIOrchestrator:
|
|||||||
self.mock_mode = config('MOCK_MODE', default='false').lower() == 'true'
|
self.mock_mode = config('MOCK_MODE', default='false').lower() == 'true'
|
||||||
|
|
||||||
async def process_request(self, message: str, request_type: str = 'chat') -> str:
|
async def process_request(self, message: str, request_type: str = 'chat') -> str:
|
||||||
"""
|
"""Route arbitrary requests, preferring the Claude CLI."""
|
||||||
Process request using the most appropriate AI model with fallback.
|
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':
|
if request_type == 'generate' or request_type == 'analyze':
|
||||||
# Use GLM4.6 for structured tasks and fall back to CLI if needed
|
logger.info("Falling back to GLM4.6 HTTP for structured request")
|
||||||
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")
|
|
||||||
return await self.glm_client.complete(message)
|
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]:
|
def _get_mock_project_config(self, user_message: str) -> Dict[str, Any]:
|
||||||
"""Generate a realistic mock project configuration"""
|
"""Generate a realistic mock project configuration"""
|
||||||
message_lower = user_message.lower()
|
message_lower = user_message.lower()
|
||||||
@@ -497,61 +504,23 @@ class AIOrchestrator:
|
|||||||
logger.info("Using mock mode for project generation")
|
logger.info("Using mock mode for project generation")
|
||||||
return self._get_mock_project_config(user_message)
|
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:
|
try:
|
||||||
# First, analyze the request with GLM4.6
|
|
||||||
analysis = await self.glm_client.analyze_music_request(user_message)
|
analysis = await self.glm_client.analyze_music_request(user_message)
|
||||||
|
prompt = self._build_project_prompt(analysis)
|
||||||
# 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
|
|
||||||
}}
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
|
|
||||||
response = await self.glm_client.complete(prompt, temperature=0.4)
|
response = await self.glm_client.complete(prompt, temperature=0.4)
|
||||||
|
|
||||||
if not response.startswith("Error:"):
|
if isinstance(response, str) and not response.startswith("Error:"):
|
||||||
try:
|
config = self._decode_project_json(response)
|
||||||
config = json.loads(response)
|
if config:
|
||||||
logger.info(f"Generated project config: {config['name']}")
|
logger.info(f"Generated project config via GLM HTTP: {config['name']}")
|
||||||
return self.sample_library.populate_project(config)
|
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:
|
except Exception as e:
|
||||||
logger.warning(f"GLM4.6 project generation failed: {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."""
|
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 using the minimax chat method, but fall back if it fails
|
||||||
try:
|
try:
|
||||||
response = await self.minimax_client.chat(message, history)
|
response = await self.minimax_client.chat(message, history)
|
||||||
@@ -621,20 +595,6 @@ class AIOrchestrator:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"GLM4.6 error: {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
|
# Final fallback to mock
|
||||||
logger.info("All APIs failed, using mock response")
|
logger.info("All APIs failed, using mock response")
|
||||||
return self._get_mock_chat_response(message)
|
return self._get_mock_chat_response(message)
|
||||||
@@ -664,3 +624,97 @@ class AIOrchestrator:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
return await self.glm_client.complete(prompt, temperature=0.5)
|
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
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import random
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Any
|
from typing import Dict, List, Optional, Any
|
||||||
|
|
||||||
|
from decouple import config
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ class SampleLibrary:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, root_dir: Optional[str] = None):
|
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.root_dir = Path(root_dir or default_root)
|
||||||
self.samples_by_category = self._scan_library()
|
self.samples_by_category = self._scan_library()
|
||||||
|
|
||||||
@@ -97,7 +99,12 @@ class SampleLibrary:
|
|||||||
|
|
||||||
normalized = hint.replace('\\', '/').lower()
|
normalized = hint.replace('\\', '/').lower()
|
||||||
category = normalized.split('/')[0]
|
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]:
|
def _infer_categories(self, track: Dict[str, Any]) -> List[str]:
|
||||||
name = (track.get('name') or '').lower()
|
name = (track.get('name') or '').lower()
|
||||||
@@ -130,3 +137,10 @@ class SampleLibrary:
|
|||||||
if not files:
|
if not files:
|
||||||
return None
|
return None
|
||||||
return random.choice(files)
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user