feat: pattern-based generators from real track analysis, RPP structure fixes, randomization

- Reverse-engineer drum patterns from 2 real reggaeton tracks with librosa
- Create patterns.py with extracted frequency data (kick/snare/hihat positions)
- Rewrite rhythm.py with pattern-bank generators (dembow, dense, trapico, offbeat)
- Rewrite melodic.py with section-aware generators and humanization
- Add weighted random sample selection in SampleSelector (top-5 pool)
- Add generate_structure() with randomized templates and energy variance
- Fix RPP structure: TEMPO arity (3→4 args), string quoting for empty strings
- Rewrite quick_drumloop_test.py with correct REAPER ground truth format
- Add scripts/analyze_examples.py for reverse engineering audio tracks
- Add --seed argument for reproducible generation
- 72 tests passing
This commit is contained in:
renato97
2026-05-03 16:08:07 -03:00
parent 32dafd94e0
commit 3444006411
10 changed files with 1664 additions and 285 deletions

View File

@@ -2,64 +2,90 @@
"genre": "reggaeton",
"era": "2009",
"display_name": "Reggaeton 2009 (Era de Oro)",
"description": "Reggaeton comercial 2006-2010. Daddy Yankee, Wisin y Yandel, Don Omar, Tito El Bambino, Hector El Father. Beat dembow con 808, piano stabs, brass hits.",
"description": "Reggaeton comercial 2006-2010. Daddy Yankee, Wisin y Yandel, Don Omar, Tito El Bambino, Hector El Father. Beat dembow con 808, piano stabs, brass hits. AGGRESSIVE groove, dense drum loops, GAP/BREAK section technique.",
"bpm": {
"min": 88,
"max": 102,
"default": 96
"default": 99
},
"keys": ["Am", "Dm", "Gm", "Cm", "Em", "Fm", "Bbm"],
"time_signature": [4, 4],
"ppq": 96,
"structure": {
"template": "intro-verse-chorus-verse-chorus-outro",
"sections": [
{"name": "intro", "bars": 4, "energy": 0.3},
{"name": "verse", "bars": 8, "energy": 0.6},
{"name": "chorus", "bars": 8, "energy": 0.9},
{"name": "verse2", "bars": 8, "energy": 0.6},
{"name": "chorus2", "bars": 8, "energy": 1.0},
{"name": "bridge", "bars": 4, "energy": 0.5},
{"name": "chorus3", "bars": 8, "energy": 1.0},
{"name": "outro", "bars": 4, "energy": 0.4}
]
"template": "extracted_real_tracks",
"templates": {
"extracted_real_tracks": [
{"name": "build", "bars": 16, "energy": 0.6},
{"name": "verse", "bars": 2, "energy": 0.35},
{"name": "build", "bars": 47, "energy": 0.65},
{"name": "verse", "bars": 1, "energy": 0.35},
{"name": "gap", "bars": 1, "energy": 0.05},
{"name": "drop", "bars": 2, "energy": 1.0},
{"name": "build", "bars": 5, "energy": 0.7},
{"name": "break", "bars": 2, "energy": 0.05},
{"name": "drop", "bars": 1, "energy": 0.95},
{"name": "build", "bars": 12, "energy": 0.65},
{"name": "verse", "bars": 2, "energy": 0.35},
{"name": "build", "bars": 8, "energy": 0.6}
],
"standard": [
{"name": "intro", "bars": 4, "energy": 0.3},
{"name": "verse", "bars": 8, "energy": 0.35},
{"name": "chorus", "bars": 8, "energy": 0.95},
{"name": "verse", "bars": 8, "energy": 0.35},
{"name": "chorus", "bars": 8, "energy": 0.95},
{"name": "bridge", "bars": 8, "energy": 0.4},
{"name": "chorus", "bars": 8, "energy": 0.95},
{"name": "outro", "bars": 8, "energy": 0.35}
]
},
"gap_break_energy_contrast": 50.0,
"dembow_positions": [0, 4, 8, 11, 12],
"note": "GAP/BREAK technique: 1-2 bars near-silence (-50dB) followed by loud DROP (+6dB) creates massive contrast. Real tracks use this extensively."
},
"pattern_banks": {
"dembow_classico": "extracted from 99.4 BPM track (Ejemplo 1)",
"perreo": "aggressive variant with extra kicks at beat 1.5& and 2",
"trapico": "half-time feel, kicks at beats 1 and 3 only",
"dense": "full drum loop density, highest hit frequency positions"
},
"roles": {
"drums": {
"description": "Patron dembow - kick en 1 y 2.5, snare en 2 y 4, hi-hats en corcheas",
"pattern_type": "dembow",
"description": "DENSE drum loop (NOT sparse kick-snare). Kicks at positions 4, 11, 8, 12, 9 — the dembow IS there but buried in a full loop. Pattern bank: kick_pattern_bank_notes",
"pattern_type": "drum_loop",
"preferred_plugins": ["FPC", "Fruity DrumSynth Live", "DirectWave", "Kontakt 7"],
"midi_channel": 0,
"mixer_slot": 0,
"notes_template": "dembow"
"notes_template": "drum_loop_dembow",
"bank": "dembow_classico"
},
"bass": {
"description": "808 sub bass que sigue al kick. Sostenido, octave 2.",
"description": "808 sub bass. Section-aware: follows section energy. Tresillo grouping in drop/chorus, sparse in break/gap.",
"pattern_type": "808_follow_kick",
"preferred_plugins": ["Serum 2", "Transistor Bass", "Sytrus", "3x Osc", "ravity(S)"],
"midi_channel": 1,
"mixer_slot": 1,
"octave": 2,
"notes_template": "bass_808"
"notes_template": "bass_tresillo_section_aware"
},
"harmony": {
"description": "Piano stabs en offbeats. Closed triads.",
"description": "Piano stabs in offbeats. Closed triads. Section-aware velocity.",
"pattern_type": "piano_stabs",
"preferred_plugins": ["FL Keys", "Nexus2", "Kontakt 7", "Sakura", "Pigments"],
"midi_channel": 2,
"mixer_slot": 2,
"notes_template": "piano_stabs"
"notes_template": "piano_stabs_section_aware"
},
"lead": {
"description": "Brass hit o melodia sintetizada. Hook del coro.",
"description": "Brass hit o melodia sintetizada. Hook syncopation on dembow positions (4, 11, 12). Section-aware density.",
"pattern_type": "brass_hook",
"preferred_plugins": ["Serum 2", "Omnisphere", "Harmor", "Electra", "ravity(S)"],
"midi_channel": 3,
"mixer_slot": 3,
"notes_template": "lead_hook"
"notes_template": "lead_hook_section_aware"
},
"pad": {
"description": "Pad atmosferico sutil para llenar el fondo.",
"description": "Pad atmosferico sutil para llenar el fondo. Sustained chord tones.",
"pattern_type": "sustained_pad",
"preferred_plugins": ["Harmor", "Serum 2", "Omnisphere", "FLEX", "Pigments"],
"midi_channel": 4,
@@ -83,7 +109,7 @@
"popularity": 0.9
},
{
"name": "tensión",
"name": "tension",
"chords": ["Am", "F", "C", "G"],
"beats_per_chord": 4,
"popularity": 0.7
@@ -152,5 +178,11 @@
"Rumor de Guerra - Hector El Father",
"Pose - Daddy Yankee",
"Llamé Pa Verte - Wisin y Yandel"
]
],
"analysis_notes": {
"key_finding": "The dembow IS present (positions 0, 4, 8, 11, 12 high across all instruments) but it's buried in a DENSE drum loop, NOT the textbook sparse kick-snare pattern.",
"kick_insight": "Position 4 (beat 2) is the DENSEST kick hit — not beat 1. Real tracks have kicks on almost EVERY 16th note position.",
"gap_break_technique": "1-2 bars near-silence (-50dB) followed by loud DROP (+6dB over baseline) creates massive contrast. This is a signature reggaetón technique.",
"filter_sweeps": "Spectral centroid drops detected in breakdowns, confirming HPF filtering in intro/filtered sections."
}
}