Xilp006 Cues Ingester
src.xil_pipeline.XILP006_cues_ingester
XILP006_cues_ingester.py — Cues Sheet Ingester
Parses a sound cues & music prompts markdown file into a structured asset manifest, audits the shared SFX library, and optionally:
- Generates NEW assets into
SFX/via ElevenLabs Sound Effects API - Enriches the episode SFX config with accurate prompts/durations sourced directly from the cues sheet
Pipeline position: after XILP001 (script parse), before XILU002/XILP002 (SFX stem generation).
Usage:
# Audit only — show library status, what needs generating, write manifest
python XILP006_cues_ingester.py --episode S02E03
# Same with explicit cues file path
python XILP006_cues_ingester.py --episode S02E03 \
--cues "cues/Season 2, Episode 3 Sound Cues.md"
# Generate NEW assets into SFX/ (requires ELEVENLABS_API_KEY)
python XILP006_cues_ingester.py --episode S02E03 --generate
# Enrich episode SFX config with cues-sheet prompts/durations
python XILP006_cues_ingester.py --episode S02E03 --enrich-sfx-config
# Preview sfx config changes without writing
python XILP006_cues_ingester.py --episode S02E03 \
--enrich-sfx-config --dry-run
# Full workflow: generate new assets and enrich sfx config
python XILP006_cues_ingester.py --episode S02E03 \
--generate --enrich-sfx-config
parse_duration
Parse a human-readable duration string into seconds.
Returns None for loop/loopable markers or unrecognised input.
Examples::
>>> parse_duration("60 seconds")
60.0
>>> parse_duration("2 minutes")
120.0
>>> parse_duration("90 seconds")
90.0
>>> parse_duration("Loop")
# returns None
Source code in src/xil_pipeline/XILP006_cues_ingester.py
parse_cues_markdown
Parse a cues & music prompts markdown file into a list of asset dicts.
Handles three cue sheet sections:
MUSIC CUES:### ASSET-ID (REUSE|NEW)heading blocks with**Prompt:**,**Duration:**,**Used:**on a single lineAMBIENCE: same heading-block formatSOUND EFFECTS: Markdown tables grouped under scene headings
Each returned dict has keys::
asset_id – e.g. "MUS-THEME-MAIN-01"
category – "MUSIC", "AMBIENCE", or "SFX"
reuse – True if marked (REUSE), False if (NEW)
prompt – ElevenLabs generation prompt string
duration_seconds – float seconds, or None (loop/unspecified)
loop – True for ambience and loop-marked assets
scene – scene label from SFX section, or None
Source code in src/xil_pipeline/XILP006_cues_ingester.py
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |
asset_library_path
Return the SFX/ file path for a cues-sheet asset ID.
'MUS-THEME-MAIN-01' → 'SFX/mus-theme-main-01.mp3'
Source code in src/xil_pipeline/XILP006_cues_ingester.py
asset_status
Return 'EXISTS', ' REUSE', or ' NEW' for an asset.
EXISTS— asset ID file present inSFX/REUSE— marked REUSE in cues sheet, not yet in libraryNEW— marked NEW, needs API generation
Source code in src/xil_pipeline/XILP006_cues_ingester.py
generation_duration
Return the API request duration, capped at API_MAX_DURATION.
Falls back to DEFAULT_SFX_DURATION when duration_seconds is None,
zero, or negative.
Source code in src/xil_pipeline/XILP006_cues_ingester.py
credits_for_duration
Return the credit cost for a single generation call of duration seconds.
Uses math.ceil so fractional-second requests are never underestimated.
ElevenLabs bills per API call, so each call's cost must be rounded up
independently before summing.
Source code in src/xil_pipeline/XILP006_cues_ingester.py
dry_run_report
Print a formatted audit of cues sheet assets vs. the SFX library.
Source code in src/xil_pipeline/XILP006_cues_ingester.py
generate_new_assets
Generate NEW assets via ElevenLabs Sound Effects API into SFX/.
Skips assets that already exist in the library. Assets marked REUSE are never generated here — they must be sourced from the master library.
Source code in src/xil_pipeline/XILP006_cues_ingester.py
find_sfx_config_matches
Return all sfx config keys containing the given asset ID as a substring.
Example — 'MUS-THEME-MAIN-01' matches both::
'MUSIC: MUS-THEME-MAIN-01 — EERIE INDIE FOLK, FADES UNDER'
'MUSIC: MUS-THEME-MAIN-01 — UP BRIEFLY, THEN OUT'
Source code in src/xil_pipeline/XILP006_cues_ingester.py
enrich_sfx_config
Update sfx config entries with prompts/durations from the cues sheet.
Matches assets to sfx config keys by asset ID substring. For each matched entry, updates:
prompt— replaced with the richer cues sheet descriptionduration_seconds— set to cues sheet value, capped at 30sloop— set to True for ambience assets
In dry-run mode, prints a diff of what would change without writing.
Source code in src/xil_pipeline/XILP006_cues_ingester.py
write_manifest
Write a structured JSON manifest of the parsed cues sheet assets.
Output path: cues/cues_manifest_<TAG>.json
Returns the output path.
Source code in src/xil_pipeline/XILP006_cues_ingester.py
find_cues_file
Auto-detect a cues markdown file for the given episode.
Checks for cues/cues_<slug>_<TAG>.md first, then falls back to
the sole .md file in cues/ when exactly one exists.
Source code in src/xil_pipeline/XILP006_cues_ingester.py
get_parser
Source code in src/xil_pipeline/XILP006_cues_ingester.py
main
CLI entry point for the cues sheet ingester.