目录

Lightweight Offline Audio Event Detection for OpenVela

离线端侧音频事件检测系统 — 面向 OpenVela/NuttX 嵌入式部署的轻量级音频分类与告警方案。

支持 5 类音频事件 检测:background(背景噪声)、cough(咳嗽)、glass_break(玻璃破碎)、baby_cry(婴儿哭声)、dog_bark(狗叫声),并支持关键词识别(救命/帮助/报警)、INT8 量化推理与 MQTT/HTTP 远程告警上报。


系统架构

┌─────────────┐     ┌──────────────────┐     ┌─────────────┐     ┌──────────────┐
│  音频采集    │ ──▶ │  特征提取         │ ──▶ │  模型推理    │ ──▶ │  输出/告警    │
│  WAV / I2S  │     │  40维时域特征    │     │  Tiny MLP   │     │  本地告警 +   │
│  16kHz mono │     │  (5指标×8统计)  │     │  40→32→5    │     │  HTTP/MQTT上报│
└─────────────┘     └──────────────────┘     └─────────────┘     └──────────────┘

完整闭环:采集 → 预处理/特征提取 → 模型识别 → 告警,检测全流程在端侧完成;远程告警上报(HTTP/MQTT)为可选能力。


目录结构

audio-event-detection/
├── audio-event-openvela/                  # 部署版(OpenVela 构建真正使用的目录)
│   ├── openvela_app/audiodetect/          #   应用源码(同步进 openvela 树 apps/audiodetect)
│   ├── data/                              #   测试 WAV + 关键词模板
│   ├── docs/、scripts/
├── audio-event-openvela-src/audio-event-openvela/   # 源码版
│   ├── python/                            # 训练/评估/导出/上位机
│   │   ├── synthetic_data_generator.py / prepare_data.py / extract_features.py
│   │   ├── train.py / noise_robustness_eval.py → models/tiny_mlp_5class_augmented.npz
│   │   ├── export_to_c.py / quantize_int8.py   # 导出 C 头(自动同步 4 个副本)
│   │   ├── alarm_server.py / alarm_demo.py / keyword_detect.py
│   │   └── embedded/audiodetect/          #   权重头副本
│   ├── embedded/audiodetect/              # Linux C 便携版(gcc 编译)
│   ├── openvela_app/audiodetect/          # OpenVela 应用源码副本
│   └── docs/、scripts/
├── demos/                                 # 一键演示脚本(Python 5 + Linux C 5 + OpenVela 1)
├── 复赛增量说明.md / README.md
└── run_openvela_demo_fixed.sh

快速开始

方式零:一键演示脚本(推荐)

demos/ 下每个功能一个脚本,三端(Python / Linux C / OpenVela 模拟器)均可一键运行:

cd demos
./demo_a_class_extend_c.sh      # A 类别扩展:5 类检测(Linux C)
./demo_b_robustness_c.sh        # B 鲁棒性:多 SNR 对比
./demo_c_model_opt_c.sh         # C 模型优化:float32 vs INT8
./demo_e_alarm_report_c.sh      # E 远程告警上报(HTTP + MQTT)
./demo_f_keyword_c.sh           # F 关键词识别(救命/帮助/报警)
./demo_openvela_all.sh          # OpenVela 模拟器:A/B/C/F 一键

Python 端对应脚本:demo_a_class_extend.pydemo_b_robustness.pydemo_c_model_opt.pydemo_e_alarm_report.pydemo_f_keyword.py。详见 demos/README.md


方式一:Python 训练 Pipeline

cd audio-event-openvela-src/audio-event-openvela/python

# 1. 生成 5 类合成数据
python synthetic_data_generator.py --count 40 --output_dir data/raw
# 2. 预处理
python prepare_data.py --raw_dir data/raw --output_dir data/processed --overwrite
# 3. 训练 5 类 clean 模型
python train.py --labels data/processed/labels.csv --model_out models/tiny_mlp_5class.npz --epochs 200
# 4. 训练增强模型(部署默认,含噪声/平移/音量/拉伸增强)
python noise_robustness_eval.py
# 5. 评估
python evaluate.py --model models/tiny_mlp_5class_augmented.npz
# 6. 单文件推理
python predict_wav.py --wav data/test/test_baby_cry.wav --model models/tiny_mlp_5class_augmented.npz
# 7. 导出 C 头文件(float + INT8,自动同步 embedded / openvela_app 部署目录)
python export_to_c.py --model models/tiny_mlp_5class_augmented.npz
python quantize_int8.py --model models/tiny_mlp_5class_augmented.npz --test_wav_dir data/test

方式二:Linux C 独立演示

cd audio-event-openvela-src/audio-event-openvela/embedded/audiodetect
make
./audiodetect ../../python/data/test/test_baby_cry.wav            # A 5类检测
./audiodetect ../../python/data/test/test_cough.wav --int8        # C INT8 推理
./audiodetect robust ../../python/data/test/test_cough.wav        # B 多 SNR
./audiodetect ../../python/data/test/test_glass.wav --report      # E 远程告警
./audiodetect keyword ../../python/data/keywords/template_救命_1.wav  # F 关键词
# 预期输出:Result: baby_cry / [ALERT] Local alarm triggered

方式三:OpenVela 模拟器端侧运行

# 1. 将应用源码同步进 OpenVela 树(apps/audiodetect),启用 CONFIG_AE_AUDIODETECT
# 2. 构建镜像
./build.sh vendor/openvela/boards/vela/configs/goldfish-arm64-v8a-ap/ --cmake -j16
# 3. 将 5 个测试 WAV 与关键词模板写入数据分区镜像(示例)
mcopy -i cmake_out/vela_goldfish-arm64-v8a-ap/vela_data.bin data/test_baby_cry.wav ::/test_baby_cry.wav
mcopy -i cmake_out/vela_goldfish-arm64-v8a-ap/vela_data.bin data/keywords/template_救命_0.wav ::/template_救命_0.wav
# 4. 启动模拟器(无头)
./emulator.sh cmake_out/vela_goldfish-arm64-v8a-ap -no-window
# 5. NSH 中运行
nsh> audiodetect /data/test_baby_cry.wav
nsh> audiodetect robust /data/test_cough.wav
nsh> audiodetect keyword /data/template_救命_0.wav

模型设计

特征提取

特征组 维度 说明
时域统计特征 40 5 种指标 × 8 种统计量(均值/标准差/最大/最小/P25/P50/P75/前后半段趋势)
合计 40 输入到 MLP 的特征维度(与 Python 训练侧一致,无 MFCC 分支)
  • 音频格式:16kHz / 单声道 / 16bit PCM
  • 帧长:400 采样点(25ms),帧移:160 采样点(10ms)
  • 短于 1 秒的音频自动零填充

网络结构

输入层:  40 维特征向量
         ↓ 标准化 (z-score)
隐藏层:  32 维 + ReLU 激活
         ↓ 线性变换
输出层:  5 维 logits
         ↓ Softmax
预测:    argmax → 类别索引
模型 结构 参数量 float 权重 INT8 权重 用途
部署模型(默认) 40→32→5 1,477 6,228 B 1,813 B OpenVela / Linux C 共用,增强模型
  • 无外部依赖,纯 C 实现,仅使用 math.h
  • 训练与部署使用同一 40 维特征管线;float 与 INT8 由同一模型导出

类别定义与触发口径

索引 类别 说明 告警触发条件
0 background 背景噪声 / 无异常事件 不触发告警
1 cough 咳嗽声 置信度 > 0.80,info
2 glass_break 玻璃破碎声 置信度 > 0.80,critical
3 baby_cry 婴儿哭声 置信度 > 0.80,warning
4 dog_bark 狗叫声 置信度 > 0.80,warning

测试结果

OpenVela Goldfish ARM64 模拟器验证

5 个测试 WAV 均在端侧模拟器上完成全流程推理(增强模型,实测全部正确):

测试音频 预测结果 告警
test_background.wav background 不触发
test_cough.wav cough [ALERT] info
test_glass.wav glass_break [ALERT] critical
test_baby_cry.wav baby_cry [ALERT] warning
test_dog_bark.wav dog_bark [ALERT] warning

一键复现:demos/demo_openvela_all.sh(完整日志见其输出的 openvela_all_smoke.log)。


模型性能

评估结果

  • 5 类合成数据集:训练/验证/测试准确率均 **100%**(python/results/evaluation.txt,混淆矩阵全对角)。
  • 噪声鲁棒性(增强模型 vs clean):10 dB 下 43% → **100%**、5 dB 下 20% → **96%**、0 dB 下 20% → **54%**,噪声环境平均提升 **+20.9%**(详见 python/results/noise_robustness_report.txt)。
  • INT8 量化:模型体积 6,228 → 1,813 字节(-70.9%),准确率 0.0% 损失(详见 python/results/int8_quantization_report.txt)。
  • 关键词识别:救命/帮助/报警,40 样本、5 档阈值全部 **100%**(python/results/keyword_eval_report.json)。
  • 远程告警:HTTP 与 MQTT 双通道送达率 4/4python/results/alarm_demo_report.json)。

以上为 Python 端评估;C 端(Linux/OpenVela)使用同一模型与特征管线,模拟器实测见“测试结果”一节。

延迟与资源占用

计算量分析

C 端部署模型(40→32→5)

阶段 运算量 (MACs) 说明
特征标准化 40 40 次减法 + 除法
隐藏层 (40→32) 1,280 40×32 矩阵乘法
ReLU 激活 32 32 次比较
输出层 (32→5) 160 32×5 矩阵乘法
Softmax 5 5 次 exp + 归一化
推理总计 ~1,522 约 3K FLOPs

特征提取为 40 维时域统计(无 FFT/MFCC),计算量极低,适合 MCU 级部署。

内存占用

组件 大小 说明
模型权重 (float) 6,228 B W1+B1+W2+B2(INT8 版 1,813 B)
标准化参数 (MEAN+STD) 320 B 40×2 × 4 bytes
PCM 输入缓冲 32 KB 16,000 × 2 bytes (int16_t)
特征向量 160 B 40 × 4 bytes (float)
隐藏层缓冲 128 B 32 × 4 bytes
关键词模块(可选) ~247 KB MFCC+DTW 静态表(不启用不占用)
基础总内存 < 40 KB 适合 MCU 级部署

延迟测试

Python 离线测量(NumPy,1000 次迭代实测)

指标 Float32 INT8
模型推理平均延迟 6.27 μs 15.15 μs

INT8 为 on-the-fly 反量化,Python 模拟略慢;C 端的主要收益是 Flash 体积减少 70.9%。

端侧延迟(OpenVela Goldfish ARM64 模拟器)

阶段 延迟 说明
WAV 文件读取 < 5 ms 32 KB 文件,FAT 分区读取
特征提取 (40维) < 1 ms 纯时域统计,无 FFT
模型推理 (MLP) < 1 ms ~1.5K MACs,Cortex-A57 @ 1.5GHz
端到端总延迟 < 10 ms 从文件读取到告警输出
音频输入长度 1 s 16,000 采样点

模拟器环境下推理在 NSH 命令响应周期内完成(日志中命令输入后立即输出结果),实测无感知延迟。实际硬件延迟取决于 I2S/PDM 采集时间。

模型体积

文件 大小 说明
model_weights.h 29,912 B float32 权重头(增强模型,部署默认)
model_weights_int8.h 9,151 B INT8 量化权重头(-69.4%)
tiny_mlp_5class.npz 16,124 B 5 类 clean 对比模型
tiny_mlp_5class_augmented.npz 8,178 B 5 类增强模型(部署默认)

硬件迁移方案

当前模拟器版本使用 WAV 文件模拟麦克风输入、printf 输出告警。迁移到 DshanPixVela-DevKit V1 等硬件时,只需替换两个模块:

模块 模拟器版本 硬件版本
音频采集 wav_reader.c mic_i2s_reader.cmic_pdm_reader.c
告警输出 printf("[ALERT]") gpio_set_value(LED_PIN, 1)buzzer_on()

以下核心模块保持不变

  • feature_extractor.c — 特征提取
  • model_infer.c — 模型推理
  • model_weights.h — 模型权重

详见 docs/migration_to_devkit.md


端侧闭环流程

                    ┌─────────────────────────────────────────────────┐
                    │              OpenVela 端侧设备                    │
                    │                                                 │
  音频输入  ──────▶ │  wav_reader.c ──▶ feature_extractor.c ──▶       │
  (WAV/I2S)         │                       40维特征                  │
                    │                          │                      │
                    │                          ▼                      │
                    │                   model_infer.c                 │
                    │                   (Tiny MLP)                    │
                    │                          │                      │
                    │              ┌───────────┴───────────┐          │
                    │              │                       │          │
                    │         background       cough/glass/baby_cry/│
                    │         (无告警)             dog_bark          │
                    │                            (置信度>0.80)       │
                    │                                      │          │
                    │                                      ▼          │
                    │                [ALERT] 本地告警 + HTTP/MQTT  │
                    │                                                 │
                    └─────────────────────────────────────────────────┘

技术栈

技术
训练框架 Python 3.10 + NumPy(PyTorch 可选)
端侧推理 纯 C99(仅依赖 math.h / stdio.h / stdlib.h
嵌入式系统 OpenVela / NuttX(Goldfish ARM64 模拟器)
数据集 合成数据(ESC-50 可导入)
模型格式 C 头文件静态数组(零依赖部署)

许可证

本项目用于音频事件检测比赛,所有代码和文档可自由用于学习和竞赛目的。ESC-50 数据集遵循其原始许可证(CC BY-NC-SA 3.0)。

关于

Audio event detection on OpenVela NuttX RTOS - 3-class (background/cough/glass_break) with 98-dim MFCC features and MLP model

23.7 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

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