refactor: migrate from FL Studio to REAPER with rpp library
Replace FL Studio binary .flp output with REAPER text-based .rpp output using the rpp Python library (Perlence/rpp). - Add core/schema.py: DAW-agnostic data types (SongDefinition, TrackDef, ClipDef, MidiNote, PluginDef) - Add reaper_builder/: RPP file generation via rpp.Element + headless render via reaper.exe CLI - Add composer/converters.py: bridge rhythm.py/melodic.py note dicts to core.schema MidiNote objects - Rewrite scripts/compose.py: real generator pipeline with --render flag - Delete src/flp_builder/, src/scanner/, mcp/, flstudio-mcp/, old scripts - Add 40 passing tests (schema, builder, converters, compose, render)
This commit is contained in:
@@ -4,6 +4,8 @@ All generators return list[dict] with format {pos, len, key, vel}.
|
||||
Designed to feed MelodicTrack notes in SongDefinition.
|
||||
"""
|
||||
|
||||
import random
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Scale definitions
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -52,6 +54,18 @@ def _clamp_vel(v: int) -> int:
|
||||
return max(1, min(127, v))
|
||||
|
||||
|
||||
def _apply_humanize(notes, humanize):
|
||||
"""Apply humanization (velocity jitter + position nudge) to note list."""
|
||||
if humanize <= 0:
|
||||
return notes
|
||||
jitter = humanize * 5
|
||||
nudge = humanize * 0.03
|
||||
for n in notes:
|
||||
n["vel"] = _clamp_vel(int(n["vel"] + random.uniform(-jitter, jitter)))
|
||||
n["pos"] = max(0, n["pos"] + random.uniform(-nudge, nudge))
|
||||
return notes
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bass: tresillo
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -61,6 +75,7 @@ def bass_tresillo(
|
||||
bars: int,
|
||||
octave: int = 3,
|
||||
velocity_mult: float = 1.0,
|
||||
humanize: float = 0.0,
|
||||
) -> list[dict]:
|
||||
"""Reggaeton tresillo bass pattern.
|
||||
|
||||
@@ -90,7 +105,7 @@ def bass_tresillo(
|
||||
vel = _clamp_vel(int(vel * velocity_mult))
|
||||
notes.append({"pos": o + pos, "len": 0.25, "key": key_note, "vel": vel})
|
||||
|
||||
return notes
|
||||
return _apply_humanize(notes, humanize)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -103,6 +118,7 @@ def lead_hook(
|
||||
octave: int = 5,
|
||||
density: float = 0.6,
|
||||
velocity_mult: float = 1.0,
|
||||
humanize: float = 0.0,
|
||||
) -> list[dict]:
|
||||
"""Simple melodic hook over 4-8 bars.
|
||||
|
||||
@@ -154,7 +170,7 @@ def lead_hook(
|
||||
else:
|
||||
pos += 0.5
|
||||
|
||||
return notes
|
||||
return _apply_humanize(notes, humanize)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -166,6 +182,7 @@ def chords_block(
|
||||
bars: int,
|
||||
octave: int = 4,
|
||||
velocity_mult: float = 1.0,
|
||||
humanize: float = 0.0,
|
||||
) -> list[dict]:
|
||||
"""Blocked chords every 2 beats (half-bar).
|
||||
|
||||
@@ -231,7 +248,7 @@ def chords_block(
|
||||
"vel": vel,
|
||||
})
|
||||
|
||||
return notes
|
||||
return _apply_humanize(notes, humanize)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -243,6 +260,7 @@ def pad_sustain(
|
||||
bars: int,
|
||||
octave: int = 4,
|
||||
velocity_mult: float = 1.0,
|
||||
humanize: float = 0.0,
|
||||
) -> list[dict]:
|
||||
"""Long sustained pad notes, one per bar.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user