Home / Audio / Production and Craft

Option B: the Layered Stem Bed Engine (and how Suno feeds it)

Updated Jun 21, 2026 · Affirmology_LayeredStemEngine_OptionB_Spec_v1.md

Summary. Status: spec. Studio only. The locked demo never changes. Proposed new queue item C30. Depends on: C26 (adds Structure.bedprofile, section markers, target length) and C3 (refactors the mix into a stage we can extend). Build order: C26, then C3, then this.

Option B: the Layered Stem Bed Engine (and how Suno feeds it)

Status: spec. Studio only. The locked demo never changes. Proposed new queue item C30. Depends on: C26 (adds Structure.bed_profile, section markers, target length) and C3 (refactors the mix into a stage we can extend). Build order: C26, then C3, then this. Answers: Jeff 2026-06-21, "how can we build Option B (layered stems mixed by the engine) with Suno?"

What Option B actually is, in one paragraph

Instead of one finished music file per track, the engine assembles the bed at render time from a LIBRARY of loopable layer files (a drone, a pad, a texture, an optional pulse, an optional motif), tagged by state, key, and tempo. At render time the engine picks the palette for the structure's bed_profile, loops or stretches the layers to the actual script length, and AUTOMATES each layer's volume across the script's sections (sparse in the induction, fuller through the install, resolving at the close), ducks the whole bed under the voice, and lays the C3 entrainment tone on top tuned to the palette's key. One small library then produces an arc-matched, evolving bed for every person and every length.

The honest truth about Suno (and the trick that makes it work)

Suno generates FINISHED songs, not clean designed layers. So you do not get "a drone stem" by asking nicely for a normal track. There are two real ways to get layers out of Suno, and we use both:

  1. GENERATE ISOLATED ELEMENTS (best for ambient/deep states). Prompt Suno for ONE element at a time, forcing everything else off ("solo sustained low drone, no percussion, no melody, no chord changes, minimal"). Each generation IS a clean layer. Because ambient layers have no strict beat, independent generations sit together fine even if they were made separately. This is the primary path for sleep, journey, and morning beds, and it works today.

  2. SPLIT A FINISHED TRACK INTO STEMS (best for rhythmic/activation states). For anything with a beat, independently generated layers will not lock to the same grid, so instead generate ONE rich track and separate it into parts that all share the same key, tempo, and grid. Two ways to split: Suno's own stem feature on paid plans, OR Demucs, a free open-source separator that runs locally in Python (so we are not dependent on Suno's paid tier and can even automate it). The trade-off is some separation artifacts, acceptable for a bed sitting under a voice.

Recommendation: start with path 1 for the deep/ambient states (cleanest, easiest, highest value), add path 2 later for activation beds.

The library spec (what we store)

A folder tree the engine reads:

stems/
  sleep/
    palette_warm_c/
      drone.wav
      pad.wav
      texture.wav
      manifest.json
  journey/
    palette_dmin_60/
      ...

manifest.json per palette: - state: sleep | journey | morning | activation - palette_id, key, bpm - layers: a list of {role: drone|pad|texture|pulse|motif, file, loopable: true/false, base_gain_db, intensity: low|med|high, lufs} - notes: any headphone/loop caveats The manifest is the contract between the content (Suno) side and the engine side. If a file is tagged correctly, the engine can use it.

The engine (the bed assembler in audio_mix.py)

A new function in the same mix stage as the C3 tones. Inputs: the structure's bed_profile (C26) to pick the palette, the script's section markers + target length (C26), and the QC gate (unchanged). Logic: 1. SELECT the palette for the bed_profile (fallback to a single preset bed if no stem palette exists, so nothing breaks). 2. BUILD THE BED ARC per pace. A small declarative map of which layers are active in which section and at what gain. Example deep arc: induction = drone only, low; deepen = drone + pad rising; install = drone + pad + texture swell at the section boundary; emerge = texture fades, drone resolves to silence. 3. LOOP / STRETCH each active layer seamlessly to the section's duration (ambient layers loop cleanly at their tagged loop points; lengths come from the script's actual timing, so it always fits). 4. PLACE SWELLS / TRANSITIONS at the section boundaries (which are the same markers C26 uses for pauses, so pacing and bed automation share one cue map). 5. SUM the layers, DUCK the bed under the voice (sidechain), then add the C3 tone tuned to palette key. 6. RUN audio_qc.py on the final mix. Reject on dropout or clipping, exactly as today.

Because section markers and target length already exist after C26, the engine has everything it needs to make the bed follow the words.

The Suno production workflow for Sol (numbered, do now)

  1. LOCK A PALETTE per state: pick one key and one BPM (e.g. sleep = key of C, 55 BPM; journey = D minor, 60 BPM). Write it down; every layer for that palette uses it.
  2. GENERATE ISOLATED ELEMENTS, one per role, instrumental only. Use the prompts below. Make several of each, keep the cleanest.
  3. EXPORT the highest quality the plan allows (WAV if available, else high-bitrate mp3).
  4. CLEAN + LOOP in Audacity (free): trim to a region with no sudden loud moment, set a clean loop, fade the very ends. Note the key and BPM.
  5. (Rhythmic states only) Instead of step 2, generate one full track and split it with Demucs or Suno stems into parts.
  6. TAG into manifest.json (state, palette, key, bpm, role, loopable, gain, intensity). Drop the files in stems///.
  7. LOG keepers in Affirmology_MusicAudition_Log_v1.md with the palette + key.

Isolated-element Suno prompts (one role at a time, instrumental, no vocals)

DRONE: "Solo sustained low ambient drone, single evolving low tone, no percussion, no melody, no chord changes, very minimal and warm, key of C, 2 to 3 minutes, seamless." PAD: "Solo warm analog pad, slow swelling chords, no drums, no melody lead, no bass, spacious and soft, key of C, 60 BPM feel, 2 to 3 minutes." TEXTURE / ATMOSPHERE: "Solo ambient texture, airy shimmer and distant atmosphere, no rhythm, no melody, no bass, very quiet and wide, key of C, 2 minutes." OPTIONAL MOTIF: "Solo sparse felt-piano motif, a few gentle notes with space between them, no drums, no pads, intimate, key of C, 2 minutes." OPTIONAL PULSE (activation only, or split from a full track): "Solo soft rhythmic synth pulse, steady gentle beat, no melody, no vocals, key of E minor, 90 BPM, 2 minutes." Keep every element in the palette's key so they stack cleanly and the C3 tone can match.

Honest limits (so we plan around them)

Guardrails (hard)

Acceptance tests

  1. A deep structure with a stem palette renders an evolving bed (layers measurably change gain across sections), voice intelligible, QC pass.
  2. The same structure with NO palette falls back to the single preset bed (no failure).
  3. The bed loops/stretches correctly to two different script lengths with no audible seam.
  4. The C3 tone is tuned to the palette key.
  5. The locked demo render is unchanged.

The exact paste for Claude Code (build AFTER C26 and C3)

Read Affirmology_PROJECT_STATE.md, Affirmology_LayeredStemEngine_OptionB_Spec_v1.md, Affirmology_AudioPacingActivation_C26_BuildBrief_v1.md, and Affirmology_FrequencySoundLayer_C3_Spec_v1.md.

Implement C30 the layered stem bed engine per the spec: a stems/ library with per-palette manifest.json, and a bed-assembler in audio_mix.py (same stage as the C3 tones) that selects a palette by Structure.bed_profile, builds a per-pace bed arc, loops/stretches layers to the script's section markers and target length, places swells at section boundaries, ducks under voice, normalizes layers to tagged LUFS, then adds the C3 tone tuned to the palette key. Graceful fallback to the current single preset bed when no palette exists. Keep audio_qc.py on the final mix. Studio only; demo untouched; no em dashes; vendor into affirmology-studio.

Add the five acceptance tests from the spec and a tiny sample palette (synthesized placeholder layers are fine for the test) so the suite runs without real Suno files. Show me diffs, test output, and one real evolving-bed render to listen to before deploying.

Bottom line for Jeff

Yes, Suno can build Option B, but its job is to produce ISOLATED ELEMENTS (or splittable full tracks), not finished beds. Sol generates clean single-element layers per state in a locked key, we tag them into a small library, and the engine does the evolving and the matching to each script. Start with the ambient states where it works beautifully today, and the same machinery later absorbs the professional stems we commission after funding, no rework.