diff --git a/apps/backend/prompts/phase2_system.txt b/apps/backend/prompts/phase2_system.txt index b60b3863..c9e62e7e 100644 --- a/apps/backend/prompts/phase2_system.txt +++ b/apps/backend/prompts/phase2_system.txt @@ -187,6 +187,12 @@ KICK CHARACTER (kickDetail) - kickDetail.thd — >0.2 indicates audible saturation; cite for Saturator Drive. BUT when kickDetail.isDistorted is true the source already clips — do NOT add Saturator on the kick; cite kickDetail.isDistorted for the omission. - kickDetail.harmonicRatio — high (>0.9) = clean/sub-heavy (avoid Drum Buss Crunch, which would add unwanted grit); low (<0.5) = noisy/snappy (Drum Buss Crunch helps unify the transient). +BASS CHARACTER (bassDetail) +- bassDetail.averageDecayMs → Glue Compressor Release. The measured mean bass decay sets the release band: <100 ms (punchy) → fast Release ≈50-120 ms; 100-300 ms (medium) → ≈150-250 ms; 300-600 ms (rolling) → ≈300-450 ms; 600+ ms (sustained) → 0.6-1.2 s or Auto. Cite bassDetail.averageDecayMs with bassDetail.type. SENTINEL GUARD: when bassDetail.transientCount < 2 the decay is unmeasured (no isolable bass onsets) — do NOT emit a bass release value; state that the bass decay could not be reliably measured. +- bassDetail.type directs the dynamics device: "punchy"/"medium" → a Compressor with a fast attack to tighten transients (kick-bus style); "rolling"/"sustained" → a Glue Compressor with a longer Release for level glue rather than transient control. Cite bassDetail.type with bassDetail.transientRatio. +- bassDetail.fundamentalHz → bass tuning/EQ: cross-reference with key to name the bass root before any narrow move. Honor the schema caveat — do NOT drive a filter Q within ±15 Hz of fundamentalHz without pitchDetail corroboration (the ZCR estimate biases upward on harmonic-rich basses). Cite bassDetail.fundamentalHz with key. +- bassDetail.swingPercent / bassDetail.grooveType → Groove Pool swing when rebuilding the bass as MIDI: "straight" → none; "slight-swing" → ≈8-16%; "heavy-swing"/"shuffle" → ≈25-50%, toward the measured swingPercent. This is the only swing value scoped to the bass specifically — prefer it over grooveDetail.perDrumSwing for bass humanization. Rule-only; do not template a separate card for a Groove Pool entry. + PER-DRUM SWING (Phase 1.C #3) - grooveDetail.perDrumSwing.{kick | snare | hihat} — swing values computed from the three beat-loudness bands (20-200 Hz / 200-4000 Hz / 4000-20000 Hz). Cite these together when recommending Groove pool entries, MIDI quantize amounts, or "humanize" automation — they let you say "humanize the snare 12% but keep the kick rigid" with the measurement attached. - The legacy fields `grooveDetail.kickSwing` and `grooveDetail.hihatSwing` still exist and equal `perDrumSwing.kick` / `perDrumSwing.hihat` for backward compatibility — prefer the perDrumSwing object when citing two or three drum groups so the citations don't fragment. @@ -197,6 +203,11 @@ REVERB DETAIL (Phase 1.D #5) - reverbDetail.preDelayMs — pre-delay estimate in milliseconds. Cite directly for the Reverb device Predelay parameter (`reverbDetail.preDelayMs: 42` → "Set Reverb Predelay to 42 ms"). When close to zero, the source is dry — don't recommend a reverb with audible predelay. - When `stemAnalysis.{stem}.reverbDetail` is present (Phase 1.D #5 per-stem), cite it for per-element reverb advice — e.g. "drums-bus Predelay 12 ms; other-bus Predelay 38 ms with longer highs (HighMids RT60 1.8 s) → Hall-style reverb with High Cut lowered for more damping." This is the cleanest way to recommend different reverb treatments per element. +ACID / FILTER MOVEMENT (acidDetail) and DELAY +- acidDetail.isAcid → Auto Filter on the bass-like element. When isAcid is true, recreate the 303 squelch with Auto Filter: a Lowpass Filter Type, high Resonance scaled by acidDetail.resonanceLevel (higher level → higher Resonance), raised LFO Amount, and Drive for grit; the LFO speed should track acidDetail.centroidOscillationHz. Cite acidDetail.resonanceLevel with acidDetail.centroidOscillationHz; hedge ("acid-style movement may be present") when acidDetail.confidence < 0.5, and omit the move entirely when isAcid is false. +- Delay / Echo BPM-sync: when the material is sparse enough to support audible repeats (a lead, stab, or chop — not a dense wall), add Echo or Delay with Sync on and the repeat division derived from bpm via the GROOVE CALCULATION RULE (a dotted-eighth repeat suits dub/house; a quarter-note repeat suits sparse leads). Keep Feedback modest (≈20-40%) so the tail decays within a couple of bars. Cite bpm; when rhythmDetail.tempoCurve is non-flat prefer Echo (it re-syncs to tempo drift) and say so. +- effectsDetail.gatingDetected → Beat Repeat / Gate: when gatingDetected is true, recreate the chop with Beat Repeat — match the repeat grid to effectsDetail.gatingRate (a "16th" rate → a 1/16 grid) and raise the repeat chance when effectsDetail.gatingRegularity is high (machine-like) versus a lower chance for irregular/glitch feel. For a plain on/off chop use Gate instead. Cite effectsDetail.gatingRate with effectsDetail.gatingRegularity; omit when gatingDetected is false. + CHORD TIMELINE (Phase 1.D #2) - chordDetail.chordTimeline is an array of `{startSec, endSec, label, labelLong, confidence}` segments produced by a 25-state (12 major + 12 minor + "N" no-chord) Viterbi decoder over `librosa.feature.chroma_cqt`. `label` is short form (`"Cm"`, `"Eb"`, `"N"`) and `labelLong` is the readable form (`"C minor"`, `"Eb major"`, `"N"`) — cite either. Use for arrangement-aware harmonic claims: "the build sits on Cm from 0:48 to 1:00 (confidence 0.7), then drops to Eb for 8 bars (confidence 0.6)" — gives Phase 2 a real progression to recreate via MIDI Chord Trigger or a Drum Rack chord-stab. - chordDetail.chordChangeCount is the count of unique chord-to-chord transitions in the timeline. Low values (≤3) indicate a static harmonic bed — recommend Reverb/Wide synth-pad treatments. High values (≥10) indicate active progression — recommend rhythmic chord-stab patches or a more dynamic sidechain feel. @@ -493,6 +504,12 @@ abletonRecommendations - {"device":"Glue Compressor","deviceFamily":"NATIVE","trackContext":"Master","workflowStage":"MASTER","category":"MASTERING","parameter":"Makeup","value":"2 dB","reason":"A PLR of 15 LU shows a dynamic, peaky master with headroom, so gentle bus glue plus makeup lifts perceived loudness before the limiter without crushing transients.","phase1Fields":["plr","lufsIntegrated"],"advancedTip":"Slow Attack (10-30 ms) so transients pass, Ratio 2:1-4:1, aim for 1-2 dB of gain reduction, then follow with a Limiter at -0.3 dB Ceiling."} - Valid sidechain example card (emit when pumping is measured — see SIDECHAIN ENVELOPE; omit when pumpingConfidence < 0.2): - {"device":"Compressor","deviceFamily":"NATIVE","trackContext":"Bass","workflowStage":"MIX","category":"DYNAMICS","parameter":"Sidechain","value":"On (Kick trigger); Threshold -22 dB, Ratio 6:1","reason":"Recreates the measured quarter-note ducking by routing the kick to the Compressor sidechain, with attack and release read from the envelope.","phase1Fields":["sidechainDetail.pumpingStrength","sidechainDetail.pumpingConfidence","sidechainDetail.envelopeShape32"],"advancedTip":"Set Release so gain returns by the recovery point shown in envelopeShape32 — a return by step 6 of 32 at the measured BPM is a short release; switch to the Glue Compressor for quarter/eighth glue."} +- Valid bass-dynamics example card (emit when bassDetail.averageDecayMs is measured — omit when bassDetail.transientCount < 2): + - {"device":"Glue Compressor","deviceFamily":"NATIVE","trackContext":"Bass","workflowStage":"MIX","category":"DYNAMICS","parameter":"Release","value":"a Release matched to the measured bass decay (rolling/sustained → 300 ms-1.2 s; punchy → 50-120 ms)","reason":"Sets the Glue Compressor release from the measured bass decay so the compressor recovers in step with the bass envelope instead of pumping against it.","phase1Fields":["bassDetail.averageDecayMs","bassDetail.type"],"advancedTip":"For a punchy bass (short averageDecayMs) switch to a Compressor with a fast attack to catch transients; keep the Glue Compressor for rolling or sustained basses where level glue matters more than transient control."} +- Valid acid filter-movement example card (emit when acidDetail.isAcid is true — hedge when acidDetail.confidence < 0.5): + - {"device":"Auto Filter","deviceFamily":"NATIVE","trackContext":"Bass","workflowStage":"SOUND_DESIGN","category":"EFFECTS","parameter":"Resonance","value":"high Resonance scaled to the measured acid resonance, LFO Amount up with the LFO tracking the measured centroid oscillation","reason":"Recreates the measured 303-style squelch by setting Auto Filter resonance from the detected acid resonance level and modulating the cutoff at the measured centroid-oscillation rate.","phase1Fields":["acidDetail.resonanceLevel","acidDetail.centroidOscillationHz"],"advancedTip":"Use a Lowpass Filter Type and add Drive for grit; when acidDetail.confidence is below 0.5 keep Resonance moderate and treat the movement as a steer rather than a committed patch."} +- Valid delay/echo example card (emit for sparse leads, stabs, or chops that support audible repeats): + - {"device":"Echo","deviceFamily":"NATIVE","trackContext":"Lead","workflowStage":"MIX","category":"EFFECTS","parameter":"Feedback","value":"≈30% with Sync on and the repeat division derived from the measured BPM (dotted-eighth for dub/house)","reason":"Adds a tempo-synced echo whose division and feedback follow the measured BPM so the repeats lock to the track grid instead of smearing it.","phase1Fields":["bpm","rhythmDetail.tempoCurve"],"advancedTip":"When rhythmDetail.tempoCurve is non-flat, Echo re-syncs to the drift; raise Feedback (40-60%) for a dub tail or lower it (15-25%) for a tight slap, and roll the repeats' highs off with the Echo filter so they sit behind the dry signal."} - Valid stereo example card (emit when sub-bass is not mono — omit when subBassMono is already true): - {"device":"Utility","deviceFamily":"NATIVE","trackContext":"Bass","workflowStage":"MIX","category":"STEREO","parameter":"Bass Mono","value":"On","reason":"Folds the low end to mono because the measured sub-bass correlation sits below 0.85, which risks phase cancellation on club systems.","phase1Fields":["stereoDetail.subBassCorrelation","stereoDetail.subBassMono"],"advancedTip":"Leave Bass Mono's crossover near 120 Hz; if subBassCorrelation stays low afterward, the stereo energy comes from a specific stem and should be narrowed at the source."} - Valid key/scale example card (emit when keyConfidence ≥ 0.7 — hedge instead when below):