本工程采用“MIDI 触发门控锁存”、“Push2 8轴物理手感包络算法”与“DMX 8位数值标定输出”三大核心模块并行协同架构:
[MIDI / Ableton 硬件输入 (midiin1)]
│
├─> [门控选择器 (select_long / select_short / select_beam / select_reset / select2)]
│ │
│ ▼
│ [CHOP Execute 事件回调脚本 (chopexec_*)]
│ │
│ ▼
│ [状态锁存与模式切换 (target_* / switch_* / gate_* / override_mode)]
│ │
│ ├─> [实时写入通信文件 (send_gates -> Gates.json)]
│ └─> [音频门控切分 (audio_long / audio_short -> audiodevout*)]
│
└─> [Push2 8轴力感打击垫 (final_punch ~ final_float)] (0.0 - 1.0)
│
▼
[Physical Envelope 状态机算法 (beam_pad_effects / Script CHOP)]
│
▼ (生成 chan1 ~ chan5 0.0 - 1.0 物理包络)
[Override 信号融合 (override1 / Override CHOP)]
│
▼ (替换 chan1~chan5,透传 chan6~chan13,组合成 13 通道 0.0 - 1.0 信号)
[DMX 8位数值标定器 (math2: Multiply 255)]
│
▼ (转换为 0 - 255 DMX 标准整型)
[Art-Net / DMX 硬件输出 (dmx_out)] ──> 【现场物理摇摆光束灯 (Beam Light)】
该模块基于 Script CHOP 实现,负责将 Ableton Push2 打击垫的 8 轴力感输入转换为光束灯的物理包络动作,并保证与前端墙面视觉 (SoloEffects.ts) 毫秒级对齐。
raw > 0.02 时,瞬间拉满包络 env = 1.0,记录 onsetTime 触发时间戳。若为 wring 效果,则翻转正反向标志位 dirSign。RELEASE_DEBOUNCE_MS = 70 毫秒的去抖保持期,防止手抖引发的多次误触发。env *= 0.82 ** (dt_ms / 16.67) 进行指数衰减,低于 0.015 时强行归零,确保不同帧率(掉帧)下手感绝对恒定。punch (频闪冲击):调光 ch3 = env 拉满,触发灯具自带高频频闪 ch4 = 0.75 * env,基于 onset 伪随机种子产生瞬时轴向冲击 ch1_offset。slash (侧抛甩击):持续 480ms,以 (1 - p)^0.85 幂次陡峭衰减,产生较大幅度摆动偏移 ch1_throw 及电机颤抖 ch2_jitter。press (缓升压感):使用 hold_ramp 缓升包络 1 - exp(-dt / 400ms),驱动亮度 ch3 在 0.4 ~ 1.0 之间平滑增强。wring (正反扭转摆频):强度按 Ramp 缓升,叠加 6Hz 正弦波摆动 wobble 及颤抖 ch2_jitter,每次触发自动翻转 ch5(正转/反转)。dab (轻触点亮):140ms 超短衰减,亮度最高达 0.6,伴随极小幅度轴向偏移。flick (侧甩闪击):前 35ms 产生高亮闪烁,伴随反向侧甩偏移 ch1_offset 与电机抖动。glide (限制压感):与 press 类似的 Ramp 缓升包络,但亮度上限被封顶限制在 0.5(cap=0.5)。float (正弦漂浮):连续正弦波漂浮摆动,驱动 ch1 大范围摇摆、ch3 呼吸调光及 ch2 微幅漂移。ch3 / ch4):采用 Max Pooling(最大值胜出) 算法,即 ch3 = max(contribs),防止多个打击垫同时按压时叠加爆表。ch1 / ch2):采用 Vector Sum(矢量叠加) 算法,在中心点 0.5 基础上求和,即 ch1 = clamp01(0.5 + sum(ch1_offset)),模拟多个物理力同时作用于机械轴。ch5):响应最后一次触发的 wring 旋转状态,无触发时默认保持正向(CH5_FORWARD = 0.25)。光束灯控制通道在 TD 中经 Override CHOP 融合后,统一在 math2 (Math CHOP) 节点乘以 255,转换为 0 ~ 255 标准 8 位 DMX 帧:
| DMX 通道 | 信号来源 | 原始数值范围 | Math2 标定 | 最终 DMX 值 | 物理灯具控制功能描述 |
|---|---|---|---|---|---|
| chan1 | beam_pad_effects | 0.0 ~ 1.0 | × 255 | 0 ~ 255 (中点 127.5) | Pan 水平摇摆行程(0.5 对应物理居中) |
| chan2 | beam_pad_effects | 0.0 ~ 1.0 | × 255 | 0 ~ 255 (中点 127.5) | Pan Fine 微调/高频 Jitter |
| chan3 | beam_pad_effects | 0.0 ~ 1.0 | × 255 | 0 ~ 255 | Dimmer 总调光亮度(0 为关,255 为最亮) |
| chan4 | beam_pad_effects | 0.0 ~ 1.0 | × 255 | 0 ~ 255 | Strobe 频闪速率(灯具硬件频闪发生器) |
| chan5 | beam_pad_effects | 0.25 / 0.75 | × 255 | 64 / 191 | Motor Dir 电机转向(<128 正转,>128 反转) |
| chan6 | beam_channels (透传) | 0.0 ~ 1.0 | × 255 | 0 ~ 255 | Color Macro 色彩宏/前景色选色表 |
| chan7 | beam_channels (透传) | 0.0 ~ 1.0 | × 255 | 0 ~ 255 | Gobo 图案片选择/旋转 |
| chan8 | beam_channels (透传) | 0.0 ~ 1.0 | × 255 | 0 ~ 255 | Prism 棱镜展开/旋转 |
| chan9 | beam_channels (透传) | 1.0 (基准) | × 255 | 255 | Red 红色通道(满功率输出) |
| chan10 | beam_channels (透传) | 1.0 (基准) | × 255 | 255 | Green 绿色通道(满功率输出) |
| chan11 | beam_channels (透传) | 1.0 (基准) | × 255 | 255 | Blue 蓝色通道(满功率输出) |
| chan12 | beam_channels (透传) | 1.0 (基准) | × 255 | 255 | White 白色通道(满功率输出) |
| chan13 | beam_channels (透传) | 0.0 (基准) | × 255 | 0 ~ 255 | Lamp Control / Reset 复位与控制宏 |
系统通过 5 个 CHOP Execute DAT 节点实时监听硬件 MIDI 通道(On Off to On 上升沿),控制全局状态及信号路由:
监听节点: select_long
def onOffToOn(channel, sampleIndex, val, prev):
op('target_long').par.value0 = 1
return
监听节点: select_short
def onOffToOn(channel, sampleIndex, val, prev):
op('target_short').par.value0 = 1
return
监听节点: select_beam
def onOffToOn(channel, sampleIndex, val, prev):
c = op('target_beam')
c.par.value0 = 1 if c.par.value0 == 0 else 0
return
监听节点: select_reset
def onOffToOn(channel, sampleIndex, val, prev):
op('target_long').par.value0 = 0
op('target_short').par.value0 = 0
return
监听节点: select2
def onOffToOn(channel, sampleIndex, val, prev):
c = op('override_mode')
c.par.value0 = 0 if c.par.value0 == 1 else 1
return