目录

audio_detect

端侧音频检测示例:流式 chunk 检测(RMS 假推理)、Mel 频谱 PNG 导出、以及 TFLite Micro 整文件推理-p 模式,可在 NuttX/goldfish 上运行)。

目录结构

apps/examples/audio_detect/
├── audio_detect_main.c / predict.c
├── infer_tflite.cc / infer_tflite.h    # TFLite Micro 推理
├── mel_spectrogram.c / mel_png.c
├── third_party/stb_image_write.h
├── tools/
│   ├── baseline.onnx                   # 原始训练模型(仅用于转换)
│   ├── baseline.tflite                 # onnx_to_tflite.py 生成
│   ├── onnx_to_tflite.py               # ONNX → TFLite 转换
│   ├── predict_tflite.py               # PC 端参考推理(对齐设备 -p)
│   ├── mel_ref_librosa.py              # PC 端 Mel PNG 参考
│   ├── requirements.txt
│   └── cleanup_ort.sh                  # 可选:删除旧 ORT 目录
└── Kconfig / CMakeLists.txt

三种运行模式

模式 命令 说明
chunk 检测 audio_detect -f xxx.wav 分块 RMS 假推理
仅 Mel PNG audio_detect -m -f xxx.wav 整文件 Mel + PNG
Mel + 推理 audio_detect -p -f xxx.wav Mel + PNG + TFLite 推理

Mel 预处理与训练侧一致(16 kHz、2 s、slaney、top_db=80、min-max)。


步骤 1:PC 上转换模型并验证

cd apps/examples/audio_detect/tools
pip install -r requirements.txt

# ONNX -> TFLite(输入 baseline.onnx,输出 baseline.tflite)
python3 onnx_to_tflite.py

# PC 参考推理(应与训练/ONNX 分数接近)
python3 predict_tflite.py --wav /path/to/test.wav --model baseline.tflite

转换后检查终端里的 input/output shape(典型为 input [1,256,61,1]output [1,3] float32;与 mel 行主序 [256×61] 字节布局一致)。


步骤 2:menuconfig

./build.sh vendor/openvela/boards/vela/configs/goldfish-arm64-v8a-ap/ --cmake menuconfig

导航路径(注意要按 Enter 进入子菜单,不是只勾选):

Application Configuration
  └── Examples
        └── Audio detection pipeline example   ← 设为 [*] 或 [M],再按 Enter 进入
              ├── Stack size                         → 262144(主任务:Mel/PNG)
              ├── Enable TFLite Micro inference (-p predict mode)  → [*]
              └── TFLite inference settings          ← 再按 Enter 进入
                    ├── Default TFLite model path    → /data/baseline.tflite
                    ├── TFLite tensor arena size     → 6291456(6 MB,当前模型 used≈4.8MB)
                    ├── TFLite Invoke task stack     → 8388608(8 MB,Invoke 专用)
                    ├── Number of model output classes → 3
                    └── Comma-separated class names  → background,coughing,glass_breaking

menuconfig 里显示的是英文菜单标题(上表中间列),不是 EXAMPLES_AUDIO_DETECT_* 这种符号名。
若看不到 TFLite inference settings,请先确认上一级 Enable TFLite Micro inference 已勾选为 [*]

勾选 TFLite 后会自动打开 TFLITEMICRO 及其依赖(flatbuffers/gemmlowp/kissfft/ruy),无需手动找。

Save 后退出。若改 Kconfig 后菜单没刷新,可先删缓存再 menuconfig:

rm -f cmake_out/vela_goldfish-arm64-v8a-ap/apps/*_Kconfig
./build.sh vendor/openvela/boards/vela/configs/goldfish-arm64-v8a-ap/ --cmake menuconfig

步骤 3:编译 NuttX

./build.sh vendor/openvela/boards/vela/configs/goldfish-arm64-v8a-ap/ --cmake -j$(nproc)

步骤 4:推送模型与音频

adb push apps/examples/audio_detect/tools/baseline.tflite /data/baseline.tflite
adb push audio/your.wav /data/test.wav

步骤 5:设备上运行

audio_detect -p -f /data/test.wav -M /data/baseline.tflite -o /data/mel.png

示例输出:

audio_detect: loaded 32000 samples @ 16000 Hz from /data/test.wav
audio_detect: mel spectrogram 61x256 (n_fft=1024 hop=512)
audio_detect: saved mel PNG -> /data/mel.png
audio_detect: TFLite model loaded: /data/baseline.tflite
audio_detect: prediction scores:
  [0] background       score=0.021924
  [1] coughing         score=0.977635
  [2] glass_breaking   score=0.000441
audio_detect: predicted class=1 (coughing)

PC 与设备对比:

python3 tools/predict_tflite.py --wav your.wav --model tools/baseline.tflite
adb pull /data/mel.png mel_device.png
python3 tools/mel_ref_librosa.py -i your.wav -o mel_ref.png

清理旧 ONNX Runtime 文件(可选)

已移除 ORT 编译脚本;若本地还有旧目录,可执行:

./tools/cleanup_ort.sh
# 或手动: rm -rf third_party/onnxruntime-1.26.0 third_party/deps_mirror

常见问题

menuconfig 没有 audio_detect
删除 cmake_out/.../apps/*_Kconfig 缓存后重新 --cmake

Reset board on recursive assert(Invoke 时复位)
常见原因已修复:MicroOpResolver 必须是静态生命周期(不能是 init() 里的栈变量)。
请重新编译后再试。若仍复位,检查 TFLite Invoke task stack = 8388608

Reset board on recursive assert(旧配置)
常见原因:把 Stack sizeTFLite tensor arena 都设成了 16000000(16MB)。正确配置:

  • Stack size:262144
  • TFLite tensor arena:5242880(5 MB;2 MB 对 baseline.tflite 不够
  • TFLite Invoke task stack:1048576(1 MB)

TFLite AllocateTensors failed(arena=2097152)
baseline.tflite 中间激活峰值约 4.36 MB(Greedy 规划后),2 MB arena 必然失败。
menuconfig 把 TFLite tensor arena size 改为 5242880,Save 后重新编译。

goldfish 默认开 KASAN,栈/堆越界会在 Invoke 时触发 assert 并复位。

TFLite AllocateTensors failed / arena 仍不够
baseline.tflite 激活张量峰值约 1.1 MB → 更正:**~4.36 MB**(238 个激活 buffer)。
menuconfig → TFLite tensor arena size 设为 5242880(5 MB)或 6291456(6 MB),重新编译后再试。

Didn't find op for ...
模型用了未注册的算子。在 infer_tflite.ccregister_ops() 里补充对应 Add*(参考 apps/mlearning/tflite-micro/.../op_resolver.h)。

PC 与设备分数不一致
先对比 Mel PNG;再确认 baseline.tflite 为 float32;检查 input shape 是否与 mel 256x61 一致。

onnx_to_tflite.py 失败
升级 pip install -U onnx onnx2tf tensorflow;或检查 baseline.onnx 是否含 TFLite 不支持的算子(需改模型或加 SELECT TF ops)。


许可

  • 示例代码:Apache 2.0
  • stb_image_write.h:public domain
  • TFLite Micro:Apache 2.0(由 openvela apps/mlearning/tflite-micro 集成)
关于
91.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号