如何修改aseqdump脚本过滤短时间内重复的MIDI控制变更事件
解决MIDI开关抖动导致bash脚本重复触发的问题
下面是修改后的防抖脚本,能过滤0.5秒内的重复MIDI事件,避免命令被多次触发:
#!/bin/bash # 初始化上次触发时间(秒级时间戳) last_trigger=0 # 设置防抖窗口时间(单位:秒) debounce_window=0.5 # 捕获Teensy MIDI设备的MIDI事件 aseqdump -p "Teensy MIDI" | while read -r event_line; do # 只处理Control change类型的事件 if [[ "$event_line" == *"Control change"* ]]; then # 从事件行中提取控制器编号和对应值 controller_num=$(echo "$event_line" | awk '{print $6}') control_value=$(echo "$event_line" | awk '{print $8}') # 仅响应控制器21的事件 if [ "$controller_num" -eq 21 ]; then # 获取当前精确时间戳(带小数,支持毫秒级计算) current_time=$(date +%s.%N) # 计算当前事件与上次触发的时间差 time_diff=$(echo "$current_time - $last_trigger" | bc) # 只有当时间差超过防抖窗口时,才执行命令 if (( $(echo "$time_diff > $debounce_window" | bc -l) )); then echo "检测到有效触发,执行git commit..." # 执行git commit(建议添加-m参数避免进入交互模式) git commit -m "Auto commit via MIDI controller" # 检查git commit是否执行失败 if [ $? -ne 0 ]; then echo "git commit失败,启动mousepad..." mousepad & fi # 更新上次触发时间为当前时间 last_trigger=$current_time fi fi fi done
关键逻辑说明
- 防抖机制:通过记录上次触发的时间戳,计算当前事件与上次的时间差,只有当差值超过设定的0.5秒时才执行命令,过滤掉开关抖动产生的重复事件。
- 事件提取:用
awk从aseqdump的输出行中提取控制器编号和值,确保只处理我们关心的控制器21事件。 - 浮点数计算:bash本身不支持浮点数运算,所以用
bc工具来计算时间差和做大小比较。 - 错误处理:通过
$?获取git commit的退出码,非0表示执行失败,此时启动mousepad。
使用注意事项
- 确保系统已安装
alsa-utils(包含aseqdump)和bc工具,若未安装可通过包管理器安装(如sudo apt install alsa-utils bc)。 - 建议给
git commit添加-m参数,避免进入交互模式导致脚本卡住。 - 可根据开关抖动的实际情况调整
debounce_window的值(比如改成0.3秒或0.6秒)。
内容的提问来源于stack exchange,提问作者FJurks
相关产品推荐
相关产品推荐

