初始提交:3 款纯音频游戏 + 共享引擎 + 完整文档与资产管线
- 共享引擎(app/src/main):GestureEngine 6 手势识别、AudioEngine 三层音频 (ExoPlayer BGM 交叉淡入 / 对白 ducking / SoundPool 低延迟)、Game/GameEngine 状态机接口、MainActivity 全屏封面 + TalkBack - 《声命线》storyline:末世互动广播剧,3 幕 8 抉择点 4 结局 - 《声东击西》reflex:听声辨位反应,12 波战斗 + BGM 三档 BPM 变速 - 《暗室》escape:3x3 网格密室逃脱,钥匙→铁柜→保险丝→电箱→大门谜题链 - 文档:setup(从零搭建)/ architecture(架构)/ engine-api(引擎 API)/ asset-pipeline(资产流水线)/ games/*(三款游戏设计文档) - 资产管线:Qwen3-TTS 对白 + 程序合成音效/BGM + Mureka BGM 的 gen 脚本与台账, 全部 ogg 资产入库可复现 - env.d 环境脚本:android/tts 入库;sfx/mureka 含密钥不入库,仅提交 .example.sh 模板
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Add a dynamic silence-pad node to an encoder onnx so it accepts ANY audio length: pads the sample
|
||||
axis up to the next multiple of 4096 with zeros (matches what eager does internally). argv: <in> <out>."""
|
||||
import sys, os
|
||||
import onnx
|
||||
from onnx import helper, TensorProto
|
||||
IN, OUT = sys.argv[1], sys.argv[2]
|
||||
m = onnx.load(IN, load_external_data=True); g = m.graph
|
||||
audio = g.input[0].name; adt = g.input[0].type.tensor_type.elem_type
|
||||
opset = {o.domain: o.version for o in m.opset_import}.get("", 0)
|
||||
print(f"input '{audio}' dtype={adt} opset={opset}", flush=True)
|
||||
g.initializer.extend([
|
||||
helper.make_tensor("_pc4096", TensorProto.INT64, [1], [4096]),
|
||||
helper.make_tensor("_pzeros5", TensorProto.INT64, [5], [0, 0, 0, 0, 0]),
|
||||
helper.make_tensor("_pidx2", TensorProto.INT64, [1], [2]),
|
||||
helper.make_tensor("_pc0", adt, [], [0]),
|
||||
])
|
||||
for n in g.node: # rewire consumers to the padded tensor
|
||||
for i, inp in enumerate(n.input):
|
||||
if inp == audio: n.input[i] = "_audio_pad"
|
||||
g.node.extend([ # pad = (4096 - N%4096) % 4096, pad end of axis 2
|
||||
helper.make_node("Shape", [audio], ["_pshape"], name="_pad_shape"),
|
||||
helper.make_node("Gather", ["_pshape", "_pidx2"], ["_pN"], name="_pad_gather", axis=0),
|
||||
helper.make_node("Mod", ["_pN", "_pc4096"], ["_pr"], name="_pad_mod1"),
|
||||
helper.make_node("Sub", ["_pc4096", "_pr"], ["_pt"], name="_pad_sub"),
|
||||
helper.make_node("Mod", ["_pt", "_pc4096"], ["_ppad"], name="_pad_mod2"),
|
||||
helper.make_node("Concat", ["_pzeros5", "_ppad"], ["_ppads"], name="_pad_concat", axis=0),
|
||||
helper.make_node("Pad", [audio, "_ppads", "_pc0"], ["_audio_pad"], name="_pad_pad", mode="constant"),
|
||||
])
|
||||
avail = {i.name for i in g.initializer} | {i.name for i in g.input} | {""}
|
||||
order, rem = [], list(g.node)
|
||||
while rem:
|
||||
nx, prog = [], False
|
||||
for nd in rem:
|
||||
if all(i in avail for i in nd.input): order.append(nd); [avail.add(o) for o in nd.output]; prog = True
|
||||
else: nx.append(nd)
|
||||
rem = nx
|
||||
if not prog: raise RuntimeError("topo stuck")
|
||||
del g.node[:]; g.node.extend(order)
|
||||
for f in (OUT, OUT + ".data"):
|
||||
if os.path.exists(f): os.remove(f)
|
||||
onnx.save(m, OUT, save_as_external_data=True, all_tensors_to_one_file=True, location=os.path.basename(OUT) + ".data", size_threshold=1024)
|
||||
print(f"padded encoder -> {OUT}", flush=True)
|
||||
Reference in New Issue
Block a user