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

71
scripts/compose.py Normal file
View File

@@ -0,0 +1,71 @@
#!/usr/bin/env python
"""Compose and build in one step from genre knowledge base."""
import sys
import os
import json
import argparse
from pathlib import Path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.stdout.reconfigure(encoding="utf-8")
from src.composer import compose_from_genre
from scripts.build import build_project
from src.flp_builder.writer import FLPWriter
KNOWLEDGE_DIR = Path(__file__).parent.parent / "knowledge" / "genres"
OUTPUT_DIR = Path(__file__).parent.parent / "output"
def main():
parser = argparse.ArgumentParser(description="Compose and build from genre")
parser.add_argument("genre", help="Genre filename (e.g. reggaeton_2009)")
parser.add_argument("--key", "-k", default=None, help="Override key (e.g. Am)")
parser.add_argument("--bpm", "-b", type=float, default=None, help="Override BPM")
parser.add_argument("--bars", type=int, default=None, help="Override bar count")
parser.add_argument("--output", "-o", default=None, help="Output .flp path")
args = parser.parse_args()
genre_file = KNOWLEDGE_DIR / f"{args.genre}.json"
if not genre_file.exists():
print(json.dumps({"error": f"Genre not found: {genre_file}", "available": [p.stem for p in KNOWLEDGE_DIR.glob("*.json")]}))
sys.exit(1)
overrides = {}
if args.key:
overrides["keys"] = [args.key]
if args.bpm:
overrides["bpm"] = {"default": args.bpm}
if args.bars:
overrides["structure"] = {"sections": [{"bars": args.bars}]}
composition = compose_from_genre(str(genre_file), overrides if overrides else None)
project = build_project(composition)
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
output_path = args.output or str(
OUTPUT_DIR / f"{args.genre}_{composition['meta']['key']}_{composition['meta']['bpm']}bpm.flp"
)
writer = FLPWriter(project)
writer.write(output_path)
result = {
"status": "ok",
"output": output_path,
"genre": args.genre,
"key": composition["meta"]["key"],
"bpm": composition["meta"]["bpm"],
"chord_progression": composition["meta"]["chord_progression"],
"tracks": [
{"role": t["role"], "notes": len(t.get("notes", []))}
for t in composition["tracks"]
],
"channel_names": [ch.name for ch in project.channels],
"total_notes": sum(len(n) for t in composition["tracks"] for n in t.get("notes", [])),
}
print(json.dumps(result, indent=2, ensure_ascii=False))
if __name__ == "__main__":
main()