feat: reggaeton production system with intelligent sample selection and FLP generation

This commit is contained in:
renato97
2026-05-02 21:40:18 -03:00
commit 4d941f3f90
62 changed files with 8656 additions and 0 deletions

0
tests/__init__.py Normal file
View File

View File

View File

@@ -0,0 +1,49 @@
"""Quick test: analyze 20 samples to verify everything works before full batch."""
import sys
import os
import time
import warnings
warnings.filterwarnings("ignore")
PROJECT = r"C:\Users\Administrator\Documents\fl_control"
os.chdir(PROJECT)
sys.path.insert(0, PROJECT)
from src.analyzer import collect_audio_files, batch_analyze
lib1 = os.path.join(PROJECT, "libreria", "reggaeton")
lib2 = os.path.join(PROJECT, "librerias", "reggaeton")
files = collect_audio_files(lib1, lib2)
print(f"Total files: {len(files)}")
# Take first 20
test_files = files[:20]
print(f"Testing with {len(test_files)} files...\n")
start = time.time()
results = batch_analyze(test_files, workers=8)
elapsed = time.time() - start
valid = [r for r in results if "error" not in r]
errors = [r for r in results if "error" in r]
print(f"\nDone in {elapsed:.1f}s ({elapsed/len(test_files):.2f}s/file)")
print(f"Valid: {len(valid)} | Errors: {len(errors)}")
for r in valid:
role = r["role"]
char = r["character"]
key = r["musical"]["key"]
bpm = r["perceptual"]["tempo"]
new = r["new_name"]
orig = os.path.basename(r["original_path"])
print(f" {orig:45s} -> {role:10s} {char:12s} {key:5s} {bpm:5.0f}bpm -> {new}")
if errors:
print(f"\nErrors:")
for e in errors:
print(f" {e}")
print(f"\n{'OK - Ready for full batch!' if len(valid) > 15 else 'Too many errors!'}")

View File

@@ -0,0 +1,41 @@
import warnings; warnings.filterwarnings("ignore")
import sys, os
sys.path.insert(0, r"C:\Users\Administrator\Documents\fl_control")
from src.analyzer import analyze_file
tests = [
("MIDILATINO Lead", r"libreria\reggaeton\SentimientoLatino2025\01\full\Midilatino_Gracias_C#_Min_102BPM_ Lead.wav"),
("MIDILATINO Bass", r"libreria\reggaeton\SentimientoLatino2025\01\full\Midilatino_Holanda_F_Min_108BPM_Bass.wav"),
("MIDILATINO Pad", r"libreria\reggaeton\SentimientoLatino2025\01\full\Midilatino_Cielo_F_Min_90BPM_Pad.wav"),
("MIDILATINO Pluck", r"libreria\reggaeton\SentimientoLatino2025\01\full\Midilatino_Cookie_E_Min_89BPM_Pluck.wav"),
("MIDILATINO Vocal", r"libreria\reggaeton\SentimientoLatino2025\01\full\Midilatino_Cookie_E_Min_89BPM_Vocal.wav"),
("MIDILATINO Arp", r"libreria\reggaeton\SentimientoLatino2025\01\full\Midilatino_Classic_G#_Min_105BPM_Arp.wav"),
("MIDILATINO Drums", r"libreria\reggaeton\SentimientoLatino2025\01\full\Midilatino_Anonaki_D#_Min_103BPM_Drums.wav"),
("MIDILATINO Full", r"libreria\reggaeton\SentimientoLatino2025\01\full\Midilatino_Anonaki_D#_Min_103BPM.wav"),
("SS_RNBL Kick", r"libreria\reggaeton\SentimientoLatino2025\02\SS_RNBL_Aqui_One_Shot_Kick.wav"),
("SS_RNBL Snare", r"libreria\reggaeton\SentimientoLatino2025\02\SS_RNBL_Aqui_One_Shot_Snare.wav"),
("SS_RNBL Hats", r"libreria\reggaeton\SentimientoLatino2025\02\SS_RNBL_Aqui_One_Shot_Hats.wav"),
("SS_RNBL Bass", r"libreria\reggaeton\SentimientoLatino2025\02\SS_RNBL_Amor_One_Shot_Bass_C_.wav"),
("SS_RNBL Lead", r"libreria\reggaeton\SentimientoLatino2025\02\SS_RNBL_Enga__o_One_Shot_Lead.wav"),
("ONESHOT LEAD", r"libreria\reggaeton\SentimientoLatino2025\01\LATINOS - ONE SHOTS\Midilatino_LEAD_Amor_C.wav"),
("ONESHOT PAD", r"libreria\reggaeton\SentimientoLatino2025\01\LATINOS - ONE SHOTS\Midilatino_PAD_Elevado_C.wav"),
("ONESHOT PLUCK", r"libreria\reggaeton\SentimientoLatino2025\01\LATINOS - ONE SHOTS\Midilatino_PLUCK_Fish_C.wav"),
("ONESHOT BRASS", r"libreria\reggaeton\SentimientoLatino2025\01\LATINOS - ONE SHOTS\Midilatino_BRASS_Thunder_C.wav"),
("ONESHOT BELL", r"libreria\reggaeton\SentimientoLatino2025\01\LATINOS - ONE SHOTS\Midilatino_BELL_Church_C.wav"),
("ONESHOT SYNTH", r"libreria\reggaeton\SentimientoLatino2025\01\LATINOS - ONE SHOTS\Midilatino_SYNTH_Voice_C.wav"),
]
base = r"C:\Users\Administrator\Documents\fl_control"
for label, path in tests:
full = os.path.join(base, path)
if not os.path.exists(full):
print(f"{label:20s} -> NOT FOUND: {path}")
continue
r = analyze_file(full)
if r and "error" not in r:
role = r["role"]
char = r["character"]
new = r["new_name"]
print(f"{label:20s} -> {role:12s} {char:10s} {new}")
else:
print(f"{label:20s} -> ERROR: {r}")

View File

@@ -0,0 +1,34 @@
import warnings; warnings.filterwarnings("ignore")
import sys, os
sys.path.insert(0, r"C:\Users\Administrator\Documents\fl_control")
from src.analyzer import analyze_file
# Use REAL paths from the library
base = r"C:\Users\Administrator\Documents\fl_control"
spack = r"libreria\reggaeton\SentimientoLatino2025\01\LATINOS - SAMPLE PACK"
tests = [
("ML Lead", os.path.join(base, spack, r"Midilatino_El_Despegue_F#_Min_92BPM\Midilatino_El_Despegue_F#_Min_92BPM_Lead.wav")),
("ML Bass", os.path.join(base, spack, r"Midilatino_Cookie_E_Min_89BPM\Midilatino_Cookie_E_Min_89BPM_Bass.wav")),
("ML Pad", os.path.join(base, spack, r"Midilatino_Cielo_F_Min_90BPM\Midilatino_Cielo_F_Min_90BPM_Pad.wav")),
("ML Pluck", os.path.join(base, spack, r"Midilatino_Get Me_E_Min_104BPM\Midilatino_Get Me_E_Min_104BPM_Pluck.wav")),
("ML Drums", os.path.join(base, spack, r"Midilatino_Anonaki_D#_Min_103BPM @PromoViDo vip Telegram\Midilatino_Anonaki_D#_Min_103BPM_Drums.wav")),
("ML FullMix", os.path.join(base, spack, r"Midilatino_Anonaki_D#_Min_103BPM @PromoViDo vip Telegram\Midilatino_Anonaki_D#_Min_103BPM.wav")),
("ML Arp", os.path.join(base, spack, r"Midilatino_Classic_G#_Min_105BPM\Midilatino_Classic_G#_Min_105BPM_Arp.wav")),
("ML Vocal", os.path.join(base, spack, r"Midilatino_Cookie_E_Min_89BPM\Midilatino_Cookie_E_Min_89BPM_Vocal.wav")),
("ML Guitar", os.path.join(base, spack, r"Midilatino_Get Me_E_Min_104BPM\Midilatino_Get Me_E_Min_104BPM_Guitar.wav")),
("ML Reese", os.path.join(base, spack, r"Midilatino_El_Despegue_F#_Min_92BPM\Midilatino_El_Despegue_F#_Min_92BPM_Reese.wav")),
("ML Synth", os.path.join(base, spack, r"Midilatino_El_Despegue_F#_Min_92BPM\Midilatino_El_Despegue_F#_Min_92BPM_Synth.wav")),
]
for label, full in tests:
if not os.path.exists(full):
print(f"{label:15s} -> NOT FOUND")
continue
r = analyze_file(full)
if r and "error" not in r:
role = r["role"]
char = r["character"]
print(f"{label:15s} -> {role:12s} {char:10s} {r['new_name']}")
else:
print(f"{label:15s} -> ERROR: {r}")

View File

@@ -0,0 +1,35 @@
import sys, os, warnings
warnings.filterwarnings('ignore')
sys.path.insert(0, r'C:\Users\Administrator\Documents\fl_control')
os.chdir(r'C:\Users\Administrator\Documents\fl_control')
from src.analyzer import analyze_file
tests = [
('KICK', r'libreria\reggaeton\kick\kick nes 1.wav'),
('SNARE', r'libreria\reggaeton\snare\snare nes 1.wav'),
('HIHAT', r'librerias\reggaeton\reggaeton 2\hi-hat (para percs normalmente)\hi-hat 1.wav'),
('BASS', r'librerias\reggaeton\3. ONE SHOTS\Bass Reventado (c) @dastin.prod.wav'),
('DRUMLOOP', r'librerias\reggaeton\4. DRUM LOOPS\LOOP 2 90bpm @dastin.prod.wav'),
('FX', r'libreria\reggaeton\fx\impact.wav'),
('PERC', r'librerias\reggaeton\10. PERCS\PERC 1 @dastin.prod.wav'),
('VOCAL', r'librerias\reggaeton\11. VOCALS\AAA.wav'),
]
for label, path in tests:
full = os.path.join(r'C:\Users\Administrator\Documents\fl_control', path)
if not os.path.exists(full):
print(f'{label}: FILE NOT FOUND - {path}')
continue
r = analyze_file(full)
if r and 'error' not in r:
role = r['role']
char = r['character']
key = r['musical']['key']
bpm = r['perceptual']['tempo']
lufs = r['perceptual']['lufs']
dur = r['signal']['duration']
new = r['new_name']
print(f'{label:10s} -> role={role:10s} char={char:12s} key={key:5s} bpm={bpm:6.1f} lufs={lufs:6.1f} dur={dur:6.3f}')
print(f' new: {new}')
else:
print(f'{label}: ERROR - {r}')

42
tests/selector Normal file
View File

@@ -0,0 +1,42 @@
import sys, os, warnings
warnings.filterwarnings("ignore")
sys.path.insert(0, r"C:\Users\Administrator\Documents\fl_control")
from src.selector import SampleSelector
sel = SampleSelector()
print("=== KICKS at 95 BPM ===")
for m in sel.select(role="kick", bpm=95, limit=5):
s = m.sample
nm = s["new_name"]
ky = s["musical"]["key"]
bp = s["perceptual"]["tempo"]
ch = s["character"]
bd = m.score_breakdown
print(f" {m.score:.2f} {nm:45s} key={ky:5s} bpm={bp:5.0f} char={ch:10s} | role={bd.get('role',0):.1f} key={bd.get('key',0):.2f} bpm={bd.get('bpm',0):.2f} char={bd.get('character',0):.2f}")
print("\n=== BASS in Am at 92 BPM ===")
for m in sel.select(role="bass", key="Am", bpm=92, limit=5):
s = m.sample
nm = s["new_name"]
ky = s["musical"]["key"]
bp = s["perceptual"]["tempo"]
ch = s["character"]
print(f" {m.score:.2f} {nm:45s} key={ky:5s} bpm={bp:5.0f} char={ch}")
print("\n=== PAD in C#m ===")
for m in sel.select(role="pad", key="C#m", limit=5):
s = m.sample
print(f" {m.score:.2f} {s['new_name']:45s} key={s['musical']['key']:5s} char={s['character']}")
print("\n=== LEAD warm at 95 BPM in Am ===")
for m in sel.select(role="lead", key="Am", bpm=95, character="warm", limit=5):
s = m.sample
print(f" {m.score:.2f} {s['new_name']:45s} key={s['musical']['key']:5s} bpm={s['perceptual']['tempo']:5.0f} char={s['character']}")
print("\n=== VOCAL in Cm ===")
for m in sel.select(role="vocal", key="Cm", limit=5):
s = m.sample
print(f" {m.score:.2f} {s['new_name']:45s} key={s['musical']['key']:5s} char={s['character']}")
print(f"\nStats: {sel.get_stats()}")