feat: professional reggaeton production engine — 7 SDD changes, 302 tests

- section-energy: track activity matrix + volume/velocity multipliers per section
- smart-chords: ChordEngine with voice leading, inversions, 4 emotion modes
- hook-melody: melody engine with hook/stabs/smooth styles, call-and-response
- mix-calibration: Calibrator module (LUFS volumes, HPF/LPF, stereo, sends, master)
- transitions-fx: FX track with risers/impacts/sweeps at section boundaries
- sidechain: MIDI CC11 bass ducking on kick hits via DrumLoopAnalyzer
- presets-pack: role-aware plugin presets (Serum/Decapitator/Omnisphere per role)

Full SDD pipeline (propose→spec→design→tasks→apply→verify) for all 7 changes.
302/302 tests passing.
This commit is contained in:
renato97
2026-05-03 23:54:29 -03:00
parent 48bc271afc
commit 014e636889
51 changed files with 11394 additions and 113 deletions

49
scripts/_match_samples.py Normal file
View File

@@ -0,0 +1,49 @@
import json, hashlib, os
# Load our sample index
idx = json.load(open('data/sample_index.json'))
samples = idx['samples']
# Build MD5 → sample map
md5_map = {}
for s in samples:
h = s.get('file_hash', '')
if h:
md5_map[h] = s
# Ableton drumloop paths
ableton_dir = r"C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\libreria\reggaeton\drumloops"
ableton_samples = [
"100bpm filtrado drumloop.wav",
"90bpm reggaeton antiguo drumloop.wav",
"94bpm reggaeton antiguo 2 drumloop.wav",
"100bpm_gata-only_drumloop.wav",
"98bpm yera drumloop.wav",
"98bpm nachogflow drumloop.wav",
"90bpm reggaeton antiguo 3 drumloop.wav",
]
print("Matching Ableton samples to our library:\n")
for name in ableton_samples:
path = os.path.join(ableton_dir, name)
if not os.path.exists(path):
print(f" NOT FOUND: {name}")
continue
# Compute MD5
h = hashlib.md5()
with open(path, 'rb') as f:
for chunk in iter(lambda: f.read(8192), b''):
h.update(chunk)
md5 = h.hexdigest()
# Lookup in index
match = md5_map.get(md5)
if match:
print(f" {name}")
print(f" -> {match['original_name']}")
print(f" MD5: {md5}")
print(f" Path: {match['original_path']}")
else:
print(f" {name} -> NO MATCH (md5={md5})")
print()