Files
IMX6U-Game/src/Apps/Game

Tom Game 语音识别验证与板端运行

本文只覆盖 Tom Game 的关键词识别链路。Windows 侧用 Python 验证 .tflite 模型和前处理,IMX6ULL-ALPHA 板端仍走 C++ + TensorFlow Lite C API。

当前结论

  • 游戏内识别器在 src/recognition/TinyKwsRecognizer.cpp,模型默认是 src/Apps/Game/model/mlcommons-tiny-kws/models/kws_ref_model_float32.tflite。
  • Windows C++ 构建默认不启用 TFLite C API,避免在 Windows 上编译/链接 TensorFlow C++。
  • ARM framebuffer 交叉编译时默认启用 TFLite C API: CMAKE_CROSSCOMPILING && TARGET_IMX 时 TOM_GAME_ENABLE_TFLITE_C_API=ON。
  • 仓库里的 runtime/lib/tensorflow/lite/c/libtensorflowlite_c.so 是 ELF32 ARM hard-float 动态库,方向上匹配 IMX6ULL 常见的 arm-linux-gnueabihf rootfs。实际板端还需要确认 rootfs ABI、libstdc++、glibc 等运行库兼容。
  • C++ 识别器当前按 float32 输入拷贝特征,所以板端默认使用 kws_ref_model_float32.tflite。不要把默认模型直接换成 kws_ref_model.tflite,它通常是量化模型,C++ 输入字节数会不匹配。
  • 12 个模型类别是 Down, Go, Left, No, Off, On, Right, Stop, Up, Yes, Silence, Unknown。游戏当前只把 Up 做成跳跃,Stop 回到空闲,其它命令识别到后暂不触发动作。

Windows Conda Python 验证

Python 验证脚本:

src\Apps\Game\tools\kws_python_test.py

脚本复刻当前 C++ 识别器的主要前处理:转单声道、线性重采样到 16 kHz、 静音裁剪、1 秒窗口、50% 滑窗、Hann + FFT + mel + MFCC。这样 Windows 验证结果更接近板端 C++ 逻辑,而不是 TI 原始 demo 的 librosa 路径。

建议用干净 Conda 环境,避免 base 环境里 TensorFlow、NumPy、ml_dtypes 二进制包互相冲突:

conda create -n imx6u-kws python=3.10 -y
conda activate imx6u-kws
python -m pip install --upgrade pip
python -m pip install numpy sounddevice tensorflow

如果你的环境能安装 tflite-runtime,脚本会优先使用它;否则自动回退到 tensorflow.lite.Interpreter。先检查解释器能否导入:

python -c "import numpy; print(numpy.__version__)"
python -c "import tensorflow as tf; print(tf.__version__)"

用仓库自带 WAV 做离线测试:

python src\Apps\Game\tools\kws_python_test.py --wav src\Apps\Game\model\mlcommons-tiny-kws\down_0c40e715_nohash_0.wav
python src\Apps\Game\tools\kws_python_test.py --wav src\Apps\Game\model\mlcommons-tiny-kws\no_0cb74144_nohash_1.wav

列出 Windows 麦克风设备:

python src\Apps\Game\tools\kws_python_test.py --list-devices

录音验证,--device 换成上一步看到的输入设备编号或名称:

python src\Apps\Game\tools\kws_python_test.py --record 1.5 --device 1 --mic-rate 48000

保存录音,便于复测同一段声音:

python src\Apps\Game\tools\kws_python_test.py --record 1.5 --device 1 --mic-rate 48000 --save-wav tmp\kws_test.wav
python src\Apps\Game\tools\kws_python_test.py --wav tmp\kws_test.wav

常用参数:

  • --model <path>:指定 .tflite 模型,默认是 float32 KWS 模型。
  • --threshold 0.75:命令置信度阈值,和 C++ 默认值一致。
  • --topk 5:输出前几个类别概率。
  • --no-trim:关闭静音裁剪,用于排查前处理差异。

IMX6ULL-ALPHA 板端构建

板端 C++ 路径需要两类 TensorFlow Lite 文件:

  • 编译期头文件:需要 TensorFlow 源码根目录,里面要有 tensorflow/lite/c/c_api.h。
  • 运行期动态库:仓库已有 src/Apps/Game/runtime/lib/tensorflow/lite/c/libtensorflowlite_c.so。

在 Linux 主机上交叉编译 framebuffer 版本:

cmake -B build-arm-fb \
  -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-linux-gnueabihf.cmake \
  -DTARGET_IMX=ON \
  -DTOM_GAME_ENABLE_TFLITE_C_API=ON \
  -DTOM_GAME_TFLITE_INCLUDE_DIR=/path/to/tensorflow-source-root \
  -DTOM_GAME_TFLITE_LIBRARY=$PWD/src/Apps/Game/runtime/lib/tensorflow/lite/c/libtensorflowlite_c.so \
  .

cmake --build build-arm-fb --target IMX6U-Game

如果只想先确认普通游戏能不能上板,可以临时关闭识别:

cmake -B build-arm-fb-no-kws \
  -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-linux-gnueabihf.cmake \
  -DTARGET_IMX=ON \
  -DTOM_GAME_ENABLE_TFLITE_C_API=OFF \
  .

cmake --build build-arm-fb-no-kws --target IMX6U-Game

关闭后 TinyKwsRecognizer::init() 会失败并打印 warning,游戏会退回到录音复读逻辑。

IMX6ULL-ALPHA 板端部署与运行

在板端先确认 ABI:

uname -m
file /opt/imx6u-game/libtensorflowlite_c.so
readelf -h /opt/imx6u-game/libtensorflowlite_c.so

期望是 32-bit ARM / hard-float。若 rootfs 是 soft-float 或 aarch64,这个 .so 不能直接用。

部署文件示例:

ssh root@imx6u 'mkdir -p /opt/imx6u-game/model'
scp build-arm-fb/IMX6U-Game root@imx6u:/opt/imx6u-game/
scp src/Apps/Game/runtime/lib/tensorflow/lite/c/libtensorflowlite_c.so root@imx6u:/opt/imx6u-game/
scp src/Apps/Game/model/mlcommons-tiny-kws/models/kws_ref_model_float32.tflite root@imx6u:/opt/imx6u-game/model/

运行前检查麦克风:

arecord -l
arecord -D default -f S16_LE -r 16000 -c 1 -d 2 /tmp/kws_mic_test.wav
aplay /tmp/kws_mic_test.wav

当前 C++ 音频输入使用 ALSA 的 "default" 设备。如果 arecord -D default 录不到声音,需要先在板端配置 /etc/asound.conf 或 ~/.asoundrc,把 USB 麦克风设为默认输入。

启动游戏:

cd /opt/imx6u-game
export LD_LIBRARY_PATH=/opt/imx6u-game:$LD_LIBRARY_PATH
./IMX6U-Game --fps 30 --kws-model /opt/imx6u-game/model/kws_ref_model_float32.tflite --kws-threshold 0.75

如果能初始化模型,录音结束后识别到关键词时串口/终端会打印:

[INFO] Keyword recognized: Up (confidence: ...)

排查顺序

  1. IMX6U-Game 能启动并正常刷新画面。
  2. arecord -D default 能录到 16-bit 单声道音频。
  3. LD_LIBRARY_PATH 包含 libtensorflowlite_c.so 所在目录。
  4. --kws-model 指向板端真实存在的 float32 .tflite 文件。
  5. 启动日志没有 Keyword recognizer init failed。
  6. Windows Python 脚本能用同一段 WAV 识别出合理类别,再拿同一段录音去板端复测。