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)
|
||||
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
|
||||
|
||||
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 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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user