diff --git a/movie_editor/backend/timeline.py b/movie_editor/backend/timeline.py index b61c3441..08184aca 100644 --- a/movie_editor/backend/timeline.py +++ b/movie_editor/backend/timeline.py @@ -108,7 +108,7 @@ def _identity_pin_guide(media_ref: str, strength: float, *, is_pin: bool = True) "media_ref": media_ref, "frame_idx": 0, "apply_at": 0, - "strength": max(0.25, min(0.5, float(strength))), + "strength": max(0.0, min(1.0, float(strength))), } if is_pin: # Marks this entry (not prior-scene/mid-scene/template guides) as the one eligible @@ -128,14 +128,14 @@ def _prior_scene_guide(prior: Scene, strength: float) -> Optional[dict]: "source": "template", "frame_idx": 0, "apply_at": 0, - "strength": max(0.25, min(0.5, float(strength))), + "strength": max(0.0, min(1.0, float(strength))), } def _decayed_strength(base: float, scene_index: int, decay: float) -> float: if scene_index <= 0 or decay >= 0.999: return base - return max(0.25, min(0.5, base * (decay ** scene_index))) + return max(0.0, min(1.0, base * (decay ** scene_index))) def build_auto_continuity_guides(full: Project, target: Project) -> Optional[dict]: @@ -294,8 +294,9 @@ def anchor_guide_strength(scene: Scene) -> float: def _self_image_guide(media_ref: str, strength: float) -> dict: - """A frame-0 guide from the scene's OWN image (anchor_guide mode). Unlike the - continuity identity-pin guide, the strength is the user's choice (full 0..1).""" + """A frame-0 guide from the scene's OWN image (anchor_guide mode). Same full 0..1 + range as every other guide strength — the measured audio-safe band is 0.25-0.35, + but that is advice, not a clamp.""" return { "enabled": True, "source": "image", diff --git a/movie_editor/frontend/engine_settings.js b/movie_editor/frontend/engine_settings.js index ff2c21bd..87f422b8 100644 --- a/movie_editor/frontend/engine_settings.js +++ b/movie_editor/frontend/engine_settings.js @@ -182,7 +182,7 @@ { name: "decode_timestep", label: "Decode timestep", kind: "float", default: 0.05, min: 0, max: 1, step: 0.01 }, { name: "decode_tile_size", label: "Decode tile size", kind: "int", default: 0, min: 0, max: 4096, step: 64 }, { name: "mid_scene_guide", label: "Mid-scene guide", kind: "bool", default: false }, - { name: "mid_scene_guide_strength", label: "Guide strength", kind: "float", default: 0.25, min: 0.25, max: 0.5, step: 0.05, dependsOn: "mid_scene_guide" }, + { name: "mid_scene_guide_strength", label: "Guide strength", kind: "float", default: 0.25, min: 0.0, max: 1.0, step: 0.05, dependsOn: "mid_scene_guide" }, { name: "joyai_memory", label: "JoyAI-Echo memory", kind: "bool", default: false }, { name: "joyai_memory_size", label: "Memory size", kind: "int", default: 7, min: 1, max: 32, step: 1, dependsOn: "joyai_memory" }, { name: "joyai_fix_frames", label: "Pinned anchors", kind: "int", default: 3, min: 0, max: 16, step: 1, dependsOn: "joyai_memory" }, @@ -636,9 +636,9 @@ i.oninput = () => patchContinuitySettings({ [key]: parseFloat(i.value || "0") }); gAdv.append(field(label, i)); }; - num("Pin strength", cs.identity_pin_strength, "identity_pin_strength", 0.25, 0.5, 0.05); - num("Prior guide strength", cs.prior_scene_strength, "prior_scene_strength", 0.25, 0.5, 0.05); - num("Mid-scene strength", cs.mid_scene_guide_strength, "mid_scene_guide_strength", 0.25, 0.5, 0.05); + num("Pin strength", cs.identity_pin_strength, "identity_pin_strength", 0.0, 1.0, 0.05); + num("Prior guide strength", cs.prior_scene_strength, "prior_scene_strength", 0.0, 1.0, 0.05); + num("Mid-scene strength", cs.mid_scene_guide_strength, "mid_scene_guide_strength", 0.0, 1.0, 0.05); num("Guide decay / scene", cs.guide_decay, "guide_decay", 0.5, 1, 0.05); const gMan = group(pane, "Manual"); diff --git a/movie_editor/frontend/inspector.js b/movie_editor/frontend/inspector.js index 476190e7..29bb8ddf 100644 --- a/movie_editor/frontend/inspector.js +++ b/movie_editor/frontend/inspector.js @@ -546,7 +546,7 @@ const ai = el("input"); ai.type = "number"; ai.value = g.apply_at != null ? g.apply_at : 0; ai.title = "apply_at"; ai.dataset.k = `guide-${idx}-apply`; ai.oninput = () => { guides[idx] = { ...g, apply_at: parseInt(ai.value || "0", 10) }; persist(guides, true); }; - const si = el("input"); si.type = "number"; si.min = "0.25"; si.max = "0.5"; si.step = "0.05"; + const si = el("input"); si.type = "number"; si.min = "0"; si.max = "1"; si.step = "0.05"; si.value = g.strength != null ? g.strength : 0.35; si.title = "Strength"; si.dataset.k = `guide-${idx}-strength`; si.oninput = () => { guides[idx] = { ...g, strength: parseFloat(si.value || "0.35") }; persist(guides, true); }; diff --git a/samplers.py b/samplers.py index baea6fb9..5676071b 100644 --- a/samplers.py +++ b/samplers.py @@ -2270,8 +2270,8 @@ class FunPackLTXAVSceneChainSampler: "tooltip": "Experimental: append the middle frame of the previous scene as a guide for the current scene via LTX guide attention. Helps maintain character positioning across scenes.", }), "mid_scene_guide_strength": ("FLOAT", { - "default": 0.25, "min": 0.25, "max": 0.5, "step": 0.05, - "tooltip": "Guide attention strength for mid-scene anchor. 0.25 is the minimum — below that audio degrades and character appearance drifts. Above 0.35 causes spatial conflicts when scene composition shifts.", + "default": 0.25, "min": 0.0, "max": 1.0, "step": 0.05, + "tooltip": "Guide attention strength for mid-scene anchor. Full 0..1 range. 0.25-0.35 is the measured sweet spot: below 0.25 audio degrades and character appearance drifts, above 0.35 spatial conflicts appear when scene composition shifts. Outside that band is yours to explore — 0 disables the guide's pull entirely.", }), "embed_guidance": ("BOOLEAN", { "default": False, @@ -4818,7 +4818,7 @@ class FunPackLTXAVSceneChainSampler: if not chunk_tensors: return chunk, positive, negative, 0 F_chunk = self._tensor_frames(chunk_tensors[0]) - s = max(0.25, float(strength)) # same audio-safe floor as mid_scene_guide + s = max(0.0, float(strength)) # the user's value stands; 0.25-0.35 is the audio-safe band tail = 0 for i, gf in enumerate(frames): apply_at = min(max(0, F_chunk - 1), i) # prefix context: distinct early positions