Problem
The dub pipeline currently has no way to customize audio treatment per segment. All segments use the same mastering chain (apply_mastering with fixed highpass + compressor + reverb). Different scenes benefit from different audio treatment: podcast dialogue needs heavy compression, action scenes need presence boosts, cinematic scenes need reverb.
Proposed Solution
Add a per-segment effect_preset field to DubSegment that lets users choose from 6 broadcast-grade DSP presets (broadcast, cinematic, podcast, warm, bright, raw). This leverages existing, well-tested code in audio_dsp.py (apply_effects_chain, EFFECT_PRESETS, list_effect_presets()) that was previously only used in standalone TTS generation.
Scope
- Backend API + Frontend state management only (no UI component in this PR)
- Non-breaking: defaults to
broadcast preset, existing behavior unchanged
- No database schema changes
- No model changes
Files Changed
backend/api/routers/engines.py — new GET /engines/effects/presets route
backend/api/schemas.py — EffectPresetEntry + EffectPresetsResponse
backend/schemas/requests.py — effect_preset field + Pydantic validator on DubSegment
backend/api/routers/dub_generate.py — apply effect chain in TTS hot loop
backend/services/batched_tts.py — apply effect chain in batch TTS; effect_preset in SegmentSpec
backend/api/routers/generation.py — effect_preset form field in standalone /generate
backend/services/incremental.py — effect_preset in fingerprint fields
frontend/src/api/engines.ts — EffectPreset type + fetchEffectPresets()
frontend/src/api/types.ts — DubSegment type with effect_preset
frontend/src/store/dubSlice.ts — segmentEffectPresets state + actions
tests/test_effects_chain.py — 12 unit tests (pure functions, no GPU)
Verification
uv run pytest tests/test_effects_chain.py -v
Problem
The dub pipeline currently has no way to customize audio treatment per segment. All segments use the same mastering chain (
apply_masteringwith fixed highpass + compressor + reverb). Different scenes benefit from different audio treatment: podcast dialogue needs heavy compression, action scenes need presence boosts, cinematic scenes need reverb.Proposed Solution
Add a per-segment
effect_presetfield toDubSegmentthat lets users choose from 6 broadcast-grade DSP presets (broadcast, cinematic, podcast, warm, bright, raw). This leverages existing, well-tested code inaudio_dsp.py(apply_effects_chain,EFFECT_PRESETS,list_effect_presets()) that was previously only used in standalone TTS generation.Scope
broadcastpreset, existing behavior unchangedFiles Changed
backend/api/routers/engines.py— newGET /engines/effects/presetsroutebackend/api/schemas.py—EffectPresetEntry+EffectPresetsResponsebackend/schemas/requests.py—effect_presetfield + Pydantic validator onDubSegmentbackend/api/routers/dub_generate.py— apply effect chain in TTS hot loopbackend/services/batched_tts.py— apply effect chain in batch TTS;effect_presetinSegmentSpecbackend/api/routers/generation.py—effect_presetform field in standalone/generatebackend/services/incremental.py—effect_presetin fingerprint fieldsfrontend/src/api/engines.ts—EffectPresettype +fetchEffectPresets()frontend/src/api/types.ts—DubSegmenttype witheffect_presetfrontend/src/store/dubSlice.ts—segmentEffectPresetsstate + actionstests/test_effects_chain.py— 12 unit tests (pure functions, no GPU)Verification
uv run pytest tests/test_effects_chain.py -v