Files
reaper-control/src/composer/converters.py
renato97 af6d61c8a1 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)
2026-05-03 09:13:35 -03:00

65 lines
2.0 KiB
Python

"""Converters — transform generator output to MIDI notes for SongDefinition.
rhythm generators → MidiNote list (channel → GM pitch mapping)
melodic generators → MidiNote list (note["key"] = pitch directly)
"""
from __future__ import annotations
from src.core.schema import MidiNote
# ---------------------------------------------------------------------------
# GM drum pitch mapping — channels 10-16
# ---------------------------------------------------------------------------
CHANNEL_PITCH: dict[int, int] = {
10: 39, # perc (General MIDI channel 10 = percussion)
11: 36, # kick
12: 38, # snare
13: 37, # rim
14: 50, # perc2
15: 42, # hihat
16: 39, # clap
}
def rhythm_to_midi(note_dict: dict[int, list[dict]]) -> list[MidiNote]:
"""Convert rhythm generator output (channel → note list) to MidiNote list.
note_dict: {channel: [{"pos", "len", "key", "vel"}, ...]}
- channel must be in CHANNEL_PITCH (10-16)
- pitch = CHANNEL_PITCH[channel]
- start = note["pos"]
- duration = note["len"]
- velocity = note["vel"]
"""
midi_notes: list[MidiNote] = []
for channel, notes in note_dict.items():
pitch = CHANNEL_PITCH.get(channel, 60)
for note in notes:
midi_notes.append(MidiNote(
pitch=pitch,
start=note["pos"],
duration=note["len"],
velocity=note["vel"],
))
return midi_notes
def melodic_to_midi(note_list: list[dict]) -> list[MidiNote]:
"""Convert melodic generator output (list of note dicts) to MidiNote list.
note_list: [{"pos", "len", "key", "vel"}, ...]
- pitch = note["key"] (directly used, not mapped)
- start = note["pos"]
- duration = note["len"]
- velocity = note["vel"]
"""
return [
MidiNote(
pitch=note["key"],
start=note["pos"],
duration=note["len"],
velocity=note["vel"],
)
for note in note_list
]