#!/usr/bin/env python """Quick test: one drum loop repeated 4 times in track 2. This script demonstrates the CORRECT REAPER .rpp format by matching the ground truth from output/all_plugins.rpp and output/test_vst3.rpp. """ from __future__ import annotations import sys from pathlib import Path ROOT = Path(__file__).parent.parent sys.path.insert(0, str(ROOT)) from rpp import Element import rpp DRUM_LOOP = r"C:\Users\Administrator\Documents\fl_control\libreria\samples\drumloop\drumloop_D2_099_boomy_f8b5a5.wav" OUTPUT = str(ROOT / "output" / "drumloop_test.rpp") def build(): """Build a valid REAPER .rpp with drum loop items.""" # Project root — matching ground truth format from all_plugins.rpp project = Element("REAPER_PROJECT", ["0.1", "7.65/win64", "12345678901234567890", "0"]) # Project header from ground truth — tokens match exactly what REAPER expects project.append(Element("NOTES", ["0", "2"])) project.append([]) project.append(["RIPPLE", "0", "0"]) project.append(["GROUPOVERRIDE", "0", "0", "0", "0"]) project.append(["AUTOXFADE", "129"]) project.append(["ENVATTACH", "3"]) project.append(["POOLEDENVATTACH", "0"]) project.append(["TCPUIFLAGS", "0"]) project.append(["MIXERUIFLAGS", "11", "48"]) project.append(["ENVFADESZ10", "40"]) project.append(["PEAKGAIN", "1"]) project.append(["FEEDBACK", "0"]) project.append(["PANLAW", "1"]) project.append(["PROJOFFS", "0", "0", "0"]) project.append(["MAXPROJLEN", "0", "0"]) project.append(["GRID", "3199", "8", "1", "8", "1", "0", "0", "0"]) project.append(["TIMEMODE", "1", "5", "-1", "30", "0", "0", "-1", "0"]) project.append(["VIDEO_CONFIG", "0", "0", "65792"]) project.append(["PANMODE", "3"]) project.append(["PANLAWFLAGS", "3"]) project.append(["CURSOR", "0"]) project.append(["ZOOM", "100", "0", "0"]) project.append(["VZOOMEX", "6", "0"]) project.append(["USE_REC_CFG", "0"]) project.append(["RECMODE", "1"]) project.append(["SMPTESYNC", "0", "30", "100", "40", "1000", "300", "0", "0", "1", "0", "0"]) project.append(["LOOP", "0"]) project.append(["LOOPGRAN", "0", "4"]) project.append(["RECORD_PATH", "Media", ""]) project.append(Element("RECORD_CFG", [], children=["ZXZhdxgAAQ=="])) project.append([]) project.append(Element("APPLYFX_CFG", [], children=[])) project.append([]) project.append(["RENDER_FILE", ""]) project.append(["RENDER_PATTERN", ""]) project.append(["RENDER_FMT", "0", "2", "0"]) project.append(["RENDER_1X", "0"]) project.append(["RENDER_RANGE", "1", "0", "0", "0", "1000"]) project.append(["RENDER_RESAMPLE", "3", "0", "1"]) project.append(["RENDER_ADDTOPROJ", "0"]) project.append(["RENDER_STEMS", "0"]) project.append(["RENDER_DITHER", "0"]) project.append(["RENDER_TRIM", "0.000001", "0.000001", "0", "0"]) project.append(["TIMELOCKMODE", "1"]) project.append(["TEMPOENVLOCKMODE", "1"]) project.append(["ITEMMIX", "1"]) project.append(["DEFPITCHMODE", "589824", "0"]) project.append(["TAKELANE", "1"]) project.append(["SAMPLERATE", "44100", "0", "0"]) project.append([]) project.append(["LOCK", "1"]) project.append(Element("METRONOME", ["6", "2"], children=[ ["VOL", "0.25", "0.125"], ["BEATLEN", "4"], ["FREQ", "1760", "880", "1"], ["SAMPLES", "", "", "", ""], ["SPLIGNORE", "0", "0"], ["SPLDEF", "2", "660", "", "0", ""], ["SPLDEF", "3", "440", "", "0", ""], ["PATTERN", "0", "169"], ["PATTERNSTR", "ABBB"], ["MULT", "1"], ])) project.append([]) project.append(["GLOBAL_AUTO", "-1"]) # TEMPO with 4 args: bpm, time_sig_num, time_sig_den, flag project.append(["TEMPO", "99", "4", "4", "0"]) project.append(["PLAYRATE", "1", "0", "0.25", "4"]) project.append(["SELECTION", "0", "0"]) project.append(["SELECTION2", "0", "0"]) project.append(["MASTERAUTOMODE", "0"]) project.append(["MASTERTRACKHEIGHT", "0", "0"]) project.append(["MASTERPEAKCOL", "16576"]) project.append(["MASTERMUTESOLO", "0"]) project.append(["MASTERTRACKVIEW", "0", "0.6667", "0.5", "0.5", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"]) project.append(["MASTERHWOUT", "0", "0", "1", "0", "0", "0", "0", "-1"]) project.append(["MASTER_NCH", "2", "2"]) project.append(["MASTER_VOLUME", "1", "0", "-1", "-1", "1"]) project.append(["MASTER_PANMODE", "3"]) project.append(["MASTER_PANLAWFLAGS", "3"]) project.append(["MASTER_FX", "1"]) project.append(["MASTER_SEL", "0"]) project.append(Element("MASTERPLAYSPEEDENV", [], children=[ ["EGUID", "{DEF87440-E07C-4B72-B9F8-D2AC60A0D0AC}"], ["ACT", "0", "-1"], ["VIS", "0", "1", "1"], ["LANEHEIGHT", "0", "0"], ["ARM", "0"], ["DEFSHAPE", "0", "-1", "-1"], ])) project.append([]) project.append(Element("TEMPOENVEX", [], children=[ ["EGUID", "{15E58A72-7149-4783-9A04-838503786012}"], ["ACT", "1", "-1"], ["VIS", "1", "0", "1"], ["LANEHEIGHT", "0", "0"], ["ARM", "0"], ["DEFSHAPE", "1", "-1", "-1"], ])) project.append([]) project.append(["RULERHEIGHT", "86", "86"]) project.append(["RULERLANE", "1", "4", "", "0", "-1"]) project.append(["RULERLANE", "2", "8", "", "0", "-1"]) project.append([]) # Master track master_guid = "{00000000-0000-0000-0000-000000000001}" master = Element("TRACK", [master_guid]) master.append(["NAME", "master"]) master.append(["VOLPAN", "1", "0", "-1", "-1", "1"]) master.append(["PEAKCOL", "16576"]) master.append(["BEAT", "-1"]) master.append(["AUTOMODE", "0"]) master.append(["PANLAWFLAGS", "3"]) master.append(["MUTESOLO", "0", "0", "0"]) master.append(["IPHASE", "0"]) master.append(["PLAYOFFS", "0", "1"]) master.append(["ISBUS", "0", "0"]) master.append(["BUSCOMP", "0", "0", "0", "0", "0"]) master.append(["SHOWINMIX", "1", "0.6667", "0.5", "1", "0.5", "0", "0", "0", "0"]) master.append(["FIXEDLANES", "9", "0", "0", "0", "0"]) master.append(["SEL", "0"]) master.append(["REC", "0", "0", "1", "0", "0", "0", "0", "0"]) master.append(["VU", "64"]) master.append(["TRACKHEIGHT", "0", "0", "0", "0", "0", "0", "0"]) master.append(["INQ", "0", "0", "0", "0.5", "100", "0", "0", "100"]) master.append(["NCHAN", "2"]) master.append(["FX", "1"]) master.append(["TRACKID", f"{{{master_guid}}}"]) master.append(["PERF", "0"]) master.append(["MIDIOUT", "-1"]) master.append(["MAINSEND", "1", "0"]) # Master FXCHAIN master_fxchain = Element("FXCHAIN", []) master_fxchain.append(["WNDRECT", "24", "52", "655", "408"]) master_fxchain.append(["SHOW", "0"]) master_fxchain.append(["LASTSEL", "0"]) master_fxchain.append(["DOCKED", "0"]) master_fxchain.append(["BYPASS", "0", "0", "0"]) master_fxchain.append(["PRESETNAME", "Program 1"]) master_fxchain.append(["FLOATPOS", "0", "0", "0", "0"]) master_fxchain.append(["FXID", "{A0F6CA8C-99E7-4B1A-8411-CA7201811EAD}"]) master.append(master_fxchain) project.append(master) # Track 2: Drum Loop track_guid = "{00000000-0000-0000-0000-000000000002}" track = Element("TRACK", [track_guid]) track.append(["NAME", "Drum Loop"]) track.append(["VOLPAN", "0.85", "0", "-1", "-1", "1"]) track.append(["PEAKCOL", "16576"]) track.append(["BEAT", "-1"]) track.append(["AUTOMODE", "0"]) track.append(["PANLAWFLAGS", "3"]) track.append(["MUTESOLO", "0", "0", "0"]) track.append(["IPHASE", "0"]) track.append(["PLAYOFFS", "0", "1"]) track.append(["ISBUS", "0", "0"]) track.append(["BUSCOMP", "0", "0", "0", "0", "0"]) track.append(["SHOWINMIX", "1", "0.6667", "0.5", "1", "0.5", "0", "0", "0", "0"]) track.append(["FIXEDLANES", "9", "0", "0", "0", "0"]) track.append(["SEL", "1"]) track.append(["REC", "0", "0", "1", "0", "0", "0", "0", "0"]) track.append(["VU", "64"]) track.append(["TRACKHEIGHT", "0", "0", "0", "0", "0", "0", "0"]) track.append(["INQ", "0", "0", "0", "0.5", "100", "0", "0", "100"]) track.append(["NCHAN", "2"]) track.append(["FX", "1"]) track.append(["TRACKID", f"{{{track_guid}}}"]) track.append(["PERF", "0"]) track.append(["MIDIOUT", "-1"]) track.append(["MAINSEND", "1", "0"]) # 4 clips of the drum loop, each 16 beats (4 bars) loop_duration_beats = 16.0 for i in range(4): position = i * loop_duration_beats item = Element("ITEM", []) item.append(["POSITION", f"{position:.6f}"]) item.append(["LENGTH", f"{loop_duration_beats:.6f}"]) item.append(["NAME", f"Drum Loop {i+1}"]) item.append(["SOFFS", "0.0"]) item.append(["PLAYRATE", "1", "0", "0.25", "4"]) item.append(["CHANMODE", "0"]) item.append(["GUID", f"{{00000000-0000-0000-0000-0000000000{i+10:02X}}}"]) item.append(["MUTE", "0", "0"]) item.append(["LOOP", "1"]) item.append(["COLOR", "0"]) # Audio source — uses correct format source = Element("SOURCE", ["WAVE"]) source.append(["FILE", DRUM_LOOP]) item.append(source) track.append(item) project.append(track) # Write output_str = rpp.dumps(project) # Quote the version string in the header output_str = output_str.replace( "