Download ComfyUI-MiniMaxH3-Context-Loop/tests/_audio_policy_unit_test.py from dzmdd/Fast_deploy: direct link, hf CLI and curl.
- Browser
- Download file 13.9 kB
-
https://huggingface.co/dzmdd/Fast_deploy/resolve/main/ComfyUI-MiniMaxH3-Context-Loop/tests/_audio_policy_unit_test.py
- Command line
-
hf download hf://dzmdd/Fast_deploy/ComfyUI-MiniMaxH3-Context-Loop/tests/_audio_policy_unit_test.py
-
curl -L -o _audio_policy_unit_test.py https://huggingface.co/dzmdd/Fast_deploy/resolve/main/ComfyUI-MiniMaxH3-Context-Loop/tests/_audio_policy_unit_test.py
13.9 kB
| #!/usr/bin/env python3 | |
| """Independent 0.5 audio axes preserve exact 0.4 mode behavior.""" | |
| import importlib.util | |
| import json | |
| import pathlib | |
| import sys | |
| import types | |
| ROOT = pathlib.Path(__file__).resolve().parents[1] | |
| PACKAGE = "h3_audio_policy_unit" | |
| folder_paths = types.ModuleType("folder_paths") | |
| folder_paths.get_output_directory = lambda: str(ROOT) | |
| folder_paths.get_temp_directory = lambda: str(ROOT) | |
| folder_paths.get_input_directory = lambda: str(ROOT) | |
| folder_paths.get_annotated_filepath = lambda value: str(value) | |
| sys.modules["folder_paths"] = folder_paths | |
| package = types.ModuleType(PACKAGE) | |
| package.__path__ = [str(ROOT)] | |
| sys.modules[PACKAGE] = package | |
| shared_nodes = types.ModuleType(PACKAGE + ".nodes") | |
| shared_nodes.MiniMaxH3MotionContext = object | |
| shared_nodes._claim_inline_patch_ownership = lambda _conditioning=None: "test patch owner" | |
| shared_nodes._prepare_native_guide_conditioning = lambda value: value | |
| shared_nodes._resize = lambda *args: None | |
| shared_nodes._streams_from_latent = lambda *args: None | |
| sys.modules[shared_nodes.__name__] = shared_nodes | |
| spec = importlib.util.spec_from_file_location( | |
| PACKAGE + ".chain_nodes", ROOT / "chain_nodes.py") | |
| chain = importlib.util.module_from_spec(spec) | |
| sys.modules[spec.name] = chain | |
| spec.loader.exec_module(chain) | |
| PLAN_JSON = json.dumps({ | |
| "shots": [{"id": "one", "prompt": "One stable scene.", "length": 22}], | |
| }) | |
| def make_plan(audio_mode="generated_audio", policy=None): | |
| combined = None | |
| if policy is not None: | |
| combined = chain._contract_compose_chain_policy( | |
| policy, chain._contract_transition_policy("guide"), | |
| audio_context_length=22) | |
| return chain._normalize_plan( | |
| PLAN_JSON, "audio-policy-test", 64, 64, 22, | |
| "video", "head", "disabled", audio_mode, 22, | |
| 1.0, 8, 7, 18, "model-stack", 0, "guide", combined) | |
| legacy_expected = { | |
| "source_track": ("source", "on", "off"), | |
| "generated_audio": ("generated", "off", "on"), | |
| "source_plus_timeline": ("source", "on", "on"), | |
| } | |
| for mode, expected in legacy_expected.items(): | |
| plan = make_plan(mode) | |
| assert "audio_policy" not in plan["compatibility"] | |
| assert plan["compatibility"]["audio_mode"] == mode | |
| resolved = chain._resolved_audio_policy(plan) | |
| assert ( | |
| resolved["final_audio"], resolved["source_reference"], | |
| resolved["generated_continuity"]) == expected | |
| default_policy = chain._contract_audio_policy("generated", "off", "on") | |
| default_status = chain._audio_policy_summary({"audio_policy": default_policy}) | |
| assert default_policy == { | |
| "version": chain.AUDIO_POLICY_VERSION, | |
| "final_audio": "generated", | |
| "source_reference": "off", | |
| "generated_continuity": "on", | |
| } | |
| assert "final=generated/ref=off/carry=on" in default_status | |
| locked_policy = chain._contract_audio_policy( | |
| "source", "on", "on", "locked") | |
| assert locked_policy == { | |
| "version": chain.AUDIO_POLICY_VERSION, | |
| "final_audio": "source", | |
| "source_reference": "off", | |
| "generated_continuity": "off", | |
| "source_audio_target": "locked", | |
| } | |
| assert chain._audio_policy_locks_source_audio({ | |
| "audio_policy": locked_policy}) | |
| assert not chain._audio_policy_uses_source_reference({ | |
| "audio_policy": locked_policy}) | |
| assert not chain._audio_policy_uses_generated_continuity({ | |
| "audio_policy": locked_policy}) | |
| assert chain._audio_policy_requires_source({ | |
| "audio_policy": locked_policy}) | |
| assert "/target=locked" in chain._audio_policy_summary({ | |
| "audio_policy": locked_policy}) | |
| custom_policy = chain._contract_audio_policy("source", "off", "on") | |
| custom_status = chain._audio_policy_summary({"audio_policy": custom_policy}) | |
| custom = make_plan("generated_audio", custom_policy) | |
| assert custom["compatibility"]["audio_mode"] == "custom" | |
| assert custom["compatibility"]["audio_policy"] == custom_policy | |
| assert chain._audio_policy_final(custom) == "source" | |
| assert not chain._audio_policy_uses_source_reference(custom) | |
| assert chain._audio_policy_uses_generated_continuity(custom) | |
| assert chain._audio_policy_requires_source(custom) | |
| assert "audio=final=source/ref=off/carry=on" in custom["summary"] | |
| silent_policy = chain._contract_audio_policy("none", "off", "on") | |
| silent = make_plan("source_track", silent_policy) | |
| assert silent["compatibility"]["audio_mode"] == "custom" | |
| assert chain._audio_policy_final(silent) == "none" | |
| assert not chain._audio_policy_requires_source(silent) | |
| prepared_silent = chain._plan_with_source_audio(silent, None) | |
| assert prepared_silent["compatibility"]["source_audio_hash"] == "none" | |
| source_audio = { | |
| "waveform": chain.torch.linspace(-0.5, 0.5, 30000).reshape(1, 1, -1), | |
| "sample_rate": 24000, | |
| } | |
| try: | |
| chain._plan_with_source_audio(custom, None) | |
| except ValueError as exc: | |
| assert "final=source" in str(exc) | |
| assert "requires source_audio" in str(exc) | |
| else: | |
| raise AssertionError("source final policy accepted missing source audio") | |
| prepared_custom = chain._plan_with_source_audio(custom, source_audio) | |
| assert prepared_custom["compatibility"]["source_audio_hash"] == ( | |
| chain._audio_fingerprint(source_audio)) | |
| reference_policy = chain._contract_audio_policy("none", "on", "off") | |
| reference_plan = make_plan("generated_audio", reference_policy) | |
| prepared_reference = chain._plan_with_source_audio( | |
| reference_plan, source_audio) | |
| chain.PromptHistoryStore = lambda _root: types.SimpleNamespace( | |
| mark_executed=lambda *_args, **_kwargs: None) | |
| state = {"plan": prepared_reference, "index": 1} | |
| current = chain.MiniMaxH3ChainCurrent().current(state, source_audio)["result"] | |
| assert current[12] is not None | |
| assert tuple(current[12]["waveform"].shape) == (1, 1, 22000) | |
| locked_plan = chain._plan_with_source_audio( | |
| make_plan("generated_audio", locked_policy), source_audio) | |
| locked_current = chain.MiniMaxH3ChainCurrent().current( | |
| {"plan": locked_plan, "index": 1}, source_audio)["result"] | |
| assert locked_current[12] is None | |
| assert tuple(locked_current[0]["current_source_audio_target"][ | |
| "waveform"].shape) == (1, 1, 22000) | |
| assert "target-locked" in locked_current[13] | |
| lip_options = chain._contract_masked_song_options() | |
| contextual_policy = chain._contract_audio_policy( | |
| "source", "off", "off", "locked", lip_options) | |
| contextual_chain_policy = chain._contract_compose_chain_policy( | |
| contextual_policy, chain._contract_transition_policy("cut"), | |
| audio_context_length=0) | |
| contextual_plan = chain._normalize_plan( | |
| json.dumps({"shots": [ | |
| {"id": "first", "prompt": "First song scene.", "length": 73}, | |
| {"id": "second", "prompt": "Second song scene.", "length": 73}, | |
| ]}), | |
| "contextual-song-test", 64, 64, 1, "video", "head", "disabled", | |
| "generated_audio", 0, 1.0, 8, 7, 18, "model-stack", 0, "guide", | |
| contextual_chain_policy) | |
| contextual_samples = round(8.0 * source_audio["sample_rate"]) | |
| contextual_source = { | |
| "waveform": chain.torch.linspace( | |
| -0.5, 0.5, contextual_samples).reshape(1, 1, -1), | |
| "sample_rate": source_audio["sample_rate"], | |
| } | |
| contextual_plan = chain._plan_with_source_audio( | |
| contextual_plan, contextual_source) | |
| contextual_current = chain.MiniMaxH3ChainCurrent().current( | |
| {"plan": contextual_plan, "index": 2}, contextual_source)["result"] | |
| contextual_state = contextual_current[0] | |
| assert contextual_state[ | |
| "current_source_audio_target_clip_start_seconds"] == 1.0 | |
| assert int(contextual_state["current_source_audio_target"][ | |
| "waveform"].shape[-1]) == round( | |
| (1.0 + 73 / 24 + 0.2) * source_audio["sample_rate"]) | |
| contextual_dependency = contextual_state[ | |
| "current_source_reference_dependency"] | |
| assert contextual_dependency["target_start_frame"] == 73 | |
| assert contextual_dependency["target_end_frame"] == 146 | |
| assert contextual_dependency["start_frame"] == 49 | |
| assert contextual_dependency["end_frame"] == 151 | |
| assert contextual_dependency["lip_sync_options"] == lip_options | |
| contextual_scene_dependency = chain._scene_dependency_record( | |
| contextual_plan, 2, contextual_dependency) | |
| assert contextual_scene_dependency["scopes"]["global_generation"][ | |
| "lip_sync_options"] == lip_options | |
| silent_state = {"plan": prepared_silent, "index": 1} | |
| silent_current = chain.MiniMaxH3ChainCurrent().current( | |
| silent_state, None)["result"] | |
| assert silent_current[12] is None | |
| scene_policy = chain._contract_audio_policy("none", "off", "on") | |
| scene_chain_policy = chain._contract_compose_chain_policy( | |
| scene_policy, chain._contract_transition_policy("guide"), | |
| audio_context_length=5) | |
| scene_plan = chain._normalize_plan( | |
| json.dumps({"shots": [ | |
| {"id": "ref", "prompt": "Source-guided scene.", "length": 56, | |
| "source_reference": "on"}, | |
| {"id": "fresh", "prompt": "Independent generated sound.", | |
| "length": 56, "generated_continuity": "off"}, | |
| {"id": "locked", "prompt": "Exact source waveform.", "length": 56, | |
| "source_audio_target": "locked"}, | |
| ]}), | |
| "scene-audio-policy-test", 64, 64, 5, "video", "head", "disabled", | |
| "generated_audio", 5, 1.0, 8, 7, 18, "model-stack", 0, "guide", | |
| scene_chain_policy) | |
| assert scene_plan["shots"][0]["source_reference"] == "on" | |
| assert scene_plan["shots"][1]["generated_continuity"] == "off" | |
| assert scene_plan["shots"][2]["source_audio_target"] == "locked" | |
| editor_scene_plan = chain._effective_editor_plan(scene_plan) | |
| assert editor_scene_plan["shots"][0]["source_reference"] == "on" | |
| assert editor_scene_plan["shots"][1]["generated_continuity"] == "off" | |
| assert editor_scene_plan["shots"][2]["source_audio_target"] == "locked" | |
| assert chain._audio_policy_uses_source_reference( | |
| scene_plan, scene_plan["shots"][0]) | |
| assert not chain._audio_policy_uses_source_reference( | |
| scene_plan, scene_plan["shots"][1]) | |
| assert not chain._audio_policy_uses_generated_continuity( | |
| scene_plan, scene_plan["shots"][1]) | |
| assert chain._audio_policy_locks_source_audio( | |
| scene_plan, scene_plan["shots"][2]) | |
| assert chain._audio_policy_requires_source(scene_plan) | |
| try: | |
| chain._plan_with_source_audio(scene_plan, None) | |
| except ValueError as exc: | |
| assert "requires source_audio" in str(exc) | |
| else: | |
| raise AssertionError("scene source override accepted missing source audio") | |
| scene_samples = round( | |
| scene_plan["total_delivered_frames"] / 24 * source_audio["sample_rate"]) | |
| scene_audio = { | |
| "waveform": chain.torch.linspace( | |
| -0.5, 0.5, scene_samples).reshape(1, 1, -1), | |
| "sample_rate": source_audio["sample_rate"], | |
| } | |
| prepared_scene_plan = chain._plan_with_source_audio(scene_plan, scene_audio) | |
| scene_ref_current = chain.MiniMaxH3ChainCurrent().current( | |
| {"plan": prepared_scene_plan, "index": 1}, scene_audio)["result"] | |
| assert scene_ref_current[12] is not None | |
| scene_fresh_current = chain.MiniMaxH3ChainCurrent().current({ | |
| "plan": prepared_scene_plan, "index": 2, | |
| "current_source_audio_target": {"stale": True}, | |
| }, scene_audio)["result"] | |
| assert scene_fresh_current[12] is None | |
| assert "current_source_audio_target" not in scene_fresh_current[0] | |
| scene_locked_current = chain.MiniMaxH3ChainCurrent().current( | |
| {"plan": prepared_scene_plan, "index": 3}, scene_audio)["result"] | |
| assert scene_locked_current[12] is None | |
| assert scene_locked_current[0]["current_source_audio_target"] is not None | |
| ref_dependency = chain._scene_dependency_record( | |
| prepared_scene_plan, 1, | |
| chain._canonical_source_reference_dependency( | |
| prepared_scene_plan, 1, None, scene_audio)) | |
| fresh_dependency = chain._scene_dependency_record( | |
| prepared_scene_plan, 2, None) | |
| locked_dependency = chain._scene_dependency_record( | |
| prepared_scene_plan, 3, | |
| chain._canonical_source_reference_dependency( | |
| prepared_scene_plan, 3, None, scene_audio)) | |
| assert ref_dependency["scopes"]["global_generation"][ | |
| "source_reference"] == "on" | |
| assert fresh_dependency["scopes"]["incoming_boundary"][ | |
| "generated_continuity"] == "off" | |
| assert locked_dependency["scopes"]["global_generation"][ | |
| "source_audio_target"] == "locked" | |
| all_off_policy = chain._contract_audio_policy("none", "on", "off", "locked") | |
| all_off_chain = chain._contract_compose_chain_policy( | |
| all_off_policy, chain._contract_transition_policy("guide"), | |
| audio_context_length=5) | |
| all_off_plan = chain._normalize_plan( | |
| json.dumps({"shots": [{ | |
| "id": "dry", "prompt": "No source needed.", "length": 39, | |
| "source_reference": "off", "source_audio_target": "off", | |
| }]}), | |
| "scene-audio-all-off", 64, 64, 5, "video", "head", "disabled", | |
| "generated_audio", 5, 1.0, 8, 7, 18, "model-stack", 0, "guide", | |
| all_off_chain) | |
| assert not chain._audio_policy_requires_source(all_off_plan) | |
| off_reference = chain._append_tagged_reference( | |
| None, kind="video", tag="motion", value="video", | |
| content_hash="video-hash", paired_audio_policy="off") | |
| assert off_reference["entries"][0]["paired_audio_policy"] == "off" | |
| assert chain._reference_entry_contract( | |
| off_reference["entries"][0])["paired_audio_policy"] == "off" | |
| embedded_reference = chain._append_tagged_reference( | |
| None, kind="video", tag="motion_av", value="video", | |
| content_hash="video-hash", audio="audio", audio_hash="audio-hash", | |
| paired_audio_policy="embedded") | |
| assert embedded_reference["entries"][0]["paired_audio_policy"] == "embedded" | |
| try: | |
| chain._append_tagged_reference( | |
| None, kind="video", tag="broken", value="video", | |
| content_hash="video-hash", paired_audio_policy="embedded") | |
| except ValueError as exc: | |
| assert "requires paired audio" in str(exc) | |
| else: | |
| raise AssertionError("embedded paired-audio policy accepted no audio") | |
| plan_inputs = chain.MiniMaxH3ChainPlan.INPUT_TYPES() | |
| assert plan_inputs["required"]["audio_mode"][1]["default"] == ( | |
| "generated_audio") | |
| assert "audio_policy" not in plan_inputs["optional"] | |
| assert "MiniMaxH3AudioPolicy" not in chain.CHAIN_NODE_CLASS_MAPPINGS | |
| print( | |
| "audio policy: exact legacy migration, independent final/reference/carry " | |
| "axes, source requirements, Current Shot slicing, paired-reference policy, " | |
| "new defaults, and one-wire-only Plan surface pass") | |