鼾声识别的价值(场景、流程)
全球约三分之一的人口睡眠中打鼾,中年男性中比例超过 50%。鼾声不只是"吵"——它可能是单纯性打鼾、上气道阻力综合征,甚至睡眠呼吸暂停(SAS/OSAS)的预警信号,后者影响着全球数亿人的健康。对设备厂商来说,鼾声识别是睡眠产品从"记录睡眠"走向"理解睡眠"的关键一步——这类声音事件检测在床垫或手环上离线运行,数据不出设备。
三类需求场景:
- 医疗健康监测——鼾声特征结合心率变异性(HRV)与血氧饱和度(SpO₂)数据,辅助呼吸暂停事件筛查。记录的关键指标包括:鼾声指数(每小时次数)、单次持续时间、声强分布、频率特征,并生成专业睡眠质量报告供医生诊断参考
- 智能家居——智能床垫实时调床头角度;智能枕头内置充气装置调整睡姿;智能空调根据鼾声调节温度、湿度与新风量
- 移动应用——仅凭一部手机即可低成本监测整夜鼾声,自动识别异常并在需要时接入专业医疗诊断流程
图:整夜采集、事件检测、严重度分级、报告与止鼾联动
完整的夜间闭环:持续采集 → 鼾声事件检测 → 整夜统计(时长/次数/占比)→ 严重程度分级 → 睡眠报告与(中度以上)止鼾干预。全部在设备端完成,音频不出设备。
鼾声的特点(时域与频域)
时域特征
- 与呼吸周期同步的周期性——约 2–4 秒一个周期;吸气与呼气阶段能量分布不同
- 准周期包络——相邻周期振幅变化平缓
- 单次持续 0.5–2 秒——能量呈典型三段式:起始段快速上升 → 中间段相对稳定 → 结束段缓慢衰减
频域特征
- 基频约 80–120Hz——主要能量集中在100–850Hz频带,高频分量最高约 2000Hz
- 3–5 个明显谐波——能量随频率升高逐级衰减,形成特征频谱包络
- 频带占比——低频段 40–60%、中频段 30–40%、高频段不超过 10%
图:鼾声(周期性爆发)与呼吸声、翻身声对比
这是一条真实鼾声音频的波形图与梅尔频谱图。与呼吸同步的周期性事件、低频集中的能量分布一眼可见:
图:真实鼾声示例:波形(上)+ 梅尔频谱(下)
试听素材(真实样本,点击播放):
🔊 音频试听:真实鼾声样本
🔊 音频试听:另一段鼾声样本
这些特征决定了检测思路:不是"听出像打鼾的声音",而是识别出一串与呼吸同步的事件。
识别方法:预处理 → 特征提取 → 算法
信号预处理
原始音频先降噪,再分帧处理:
- 帧长 25ms——保证信号的短时平稳性
- 帧移 10ms——确保帧间信息连续性
- 汉明窗——减少频谱泄漏
特征提取
- 时域——短时能量(强度变化)、过零率(频率特性)、自相关系数(周期性)
- 频域——MFCC(模拟人耳听觉特性)、频谱质心(频率分布重心)、频带能量比(能量分布特征)
识别算法
引擎以"事件"为工作单位,而非逐帧标注:
- 先定位事件——检测能量爆发,输出每次鼾声的起止时间与强度
- 周期性验证——真正的鼾声成串出现、跟随呼吸节律;孤立的突发声(翻身、咳嗽、床架响声)不成序列,被排除
- 个体泛化——训练覆盖年龄、性别、体型差异,同时抑制空调、风扇、雨声等持续背景噪声
难点所在
个体差异大;持续背景噪声长期存在;还需把鼾声与呼吸声、体动声、床架声区分开。事件化分析 + 针对性负样本训练是应对这三者的工程答案。
准确率与性能
| 项目 | 指标 |
|---|---|
| 准确率 | 96.5% |
| 误报率 | <2% |
| 模型大小 | 0.2–1MB(INT8) |
| 推理延迟 | 灵活可调(视平台资源) |
| 采样率 | 16kHz |
| 支持平台 | ARM Linux / MIPS / x86_64;SVP / Magik 预适配 |
注:文中性能指标基于内部测试环境,实际表现取决于硬件配置与使用场景。
系统与数据呈现
图:采集、处理、引擎、输出、应用五层结构
引擎输出事件流(时间点与强度);应用层完成整夜统计、严重程度分级,并渲染睡眠报告。
图:整夜事件时间线与周趋势(示意)
一份睡眠报告通常包含:整夜事件时间线、总时长与次数对照基线、周趋势——长期视角让"变化"变得有意义。
产品形态
图:床边监测仪、智能床垫、可穿戴与止鼾设备
床边监测仪(以声学为主、免接触)、智能床垫与智能枕头(睡眠数据 + 物理干预)、可穿戴设备(腕上初筛)、以及专用止鼾设备(实时检测驱动干预动作)。
运行平台与硬件要求
模型运行在睡眠产品常见的低功耗平台上——从 100MHz 主频级芯片起步,INT8 模型在 0.2–1MB 以内,与设备主业务共享 SoC 资源。
C 接口与嵌入式集成
鼾声识别库提供简洁的流式 C 接口:调用方只需持续送入 16kHz 单声道 PCM,拼帧、Mel 预处理与模型推理全部在内部完成,帧级概率经报警策略聚合成「鼾声事件」回调输出。
完整接口声明(snore_detect.h):
/** * snore_detect.h — 鼾声识别统一接口 * * 封装 Mel 预处理 + 推理引擎 + 报警策略, 内部模型消费线程处理音频。 * 与录音模块 (audio_capture.h) 相互独立: 调用者自行决定音频来源 * (录音回调 / wav 文件 / 网络流), 通过 snore_detect_feed 送入, 数据任意大小。 * * 用法 (实时录音模式): * snore_detect_t *d = snore_detect_create(mgk_path, NULL, NULL); * snore_detect_set_listener(d, on_frame, on_onset, on_offset, NULL); * snore_detect_start(d); // 启动内部模型消费线程 * audio_capture_start(rec, capture_cb, d); // 录音回调里调 snore_detect_feed * ... * snore_detect_stop(d); // 排空缓冲, 停止线程 * snore_detect_destroy(d); * * 用法 (wav 文件模式): * snore_detect_t *d = snore_detect_create(mgk_path, NULL, NULL); * snore_detect_set_listener(d, on_frame, on_onset, on_offset, NULL); * snore_detect_start(d); * 循环读文件: snore_detect_feed(d, pcm, n); // 任意数据大小 * snore_detect_stop(d); * snore_detect_destroy(d); */#ifndefSNORE_DETECT_H#defineSNORE_DETECT_H#include<stdint.h>#ifdef__cplusplusextern"C"{#endif/* 识别事件 (报警策略输出, 用于事件结束回调) */typedefstruct{floatstart_time;/* 事件开始时间 (秒) */floatend_time;/* 事件结束时间 (秒) */floatconfidence;/* 事件置信度 */floatmax_confidence;/* 事件内最大帧置信度 */intframe_count;/* 事件持续帧数 */}snore_detect_event_t;/* 帧级回调: 每帧识别结果 (模型线程内执行) */typedefvoid(*snore_detect_frame_cb_t)(floatsnore_prob,floattimestamp,void*user_data);/* 事件开始回调: 策略判定鼾声事件开始, 只有开始时间 */typedefvoid(*snore_detect_onset_cb_t)(floatstart_time,void*user_data);/* 事件结束回调: 策略判定鼾声事件结束 (或停止识别时未结束的事件), 完整事件信息 */typedefvoid(*snore_detect_offset_cb_t)(constsnore_detect_event_t*event,void*user_data);typedefstructsnore_detect_ssnore_detect_t;/* 创建/销毁; alarm_name/alarm_params 可传 NULL (用默认策略及参数) */snore_detect_t*snore_detect_create(constchar*mgk_path,/* 模型文件路径 (必填) */constchar*alarm_name,/* 报警策略名, NULL=默认 */constchar*alarm_params);/* 策略参数 key=val,key=val, NULL=默认 */voidsnore_detect_destroy(snore_detect_t*det);/* 设置事件回调 (create 后调用, 也可在运行中调整); 不需要的回调传 NULL */voidsnore_detect_set_listener(snore_detect_t*det,snore_detect_frame_cb_ton_frame,snore_detect_onset_cb_ton_onset,snore_detect_offset_cb_ton_offset,void*user_data);/* 启动/停止识别: 启动内部模型消费线程 / 排空缓冲后停止线程 */intsnore_detect_start(snore_detect_t*det);voidsnore_detect_stop(snore_detect_t*det);intsnore_detect_is_running(snore_detect_t*det);/* 设置事件识别策略 (可在运行中调整) */intsnore_detect_set_alarm(snore_detect_t*det,constchar*alarm_name,constchar*alarm_params);/* 送入 PCM 数据 (16bit 单声道 16kHz), 线程安全, 任意数据大小 */intsnore_detect_feed(snore_detect_t*det,constint16_t*pcm,intnum_samples);#ifdef__cplusplus}#endif#endif/* SNORE_DETECT_H */最简 wav 推理示例(节选,完整文件位于 SDK 的src/snoreDetect/c/snore_demo.c):
#include<stdio.h>#include<stdlib.h>#include<stdint.h>#include"snore_detect.h"#defineDEFAULT_MGK"snore_detect.mgk"/* 模型文件 */#defineDEFAULT_WAV"test_snore.wav"/* 16kHz 单声道 16bit PCM */#defineFEED_CHUNK16000/* 每次送入 1 秒音频 *//* 帧级回调: 每帧输出鼾声概率 (约 1 秒一帧) */staticvoidon_frame(floatsnore_prob,floattimestamp,void*user_data){(void)user_data;printf("%8.2fs snore=%.4f\\n",timestamp,snore_prob);}/* 事件开始回调: 策略判定鼾声事件开始 */staticvoidon_onset(floatstart_time,void*user_data){(void)user_data;printf("[EVENT] snore start at %.2fs\\n",start_time);}/* 事件结束回调: 应用层可据此做整夜统计或分级响应 */staticvoidon_offset(constsnore_detect_event_t*ev,void*user_data){(void)user_data;printf("[EVENT] snore end at %.2fs (dur=%.2fs, conf=%.3f, frames=%d)\\n",ev->end_time,ev->end_time-ev->start_time,ev->confidence,ev->frame_count);}staticintread_wav_pcm(constchar*path,int16_t**pcm,int*n,int*sr);/* 完整实现见源文件 */intmain(void){snore_detect_t*det;int16_t*pcm=NULL;intnum_samples=0,sample_rate=0;intpos;if(read_wav_pcm(DEFAULT_WAV,&pcm,&num_samples,&sample_rate)!=0)return1;/* 1. 创建识别器: .mgk 模型 + 默认报警策略 (NULL) */det=snore_detect_create(DEFAULT_MGK,NULL,NULL);if(!det)return1;/* 2. 注册回调 (均为可选) */snore_detect_set_listener(det,on_frame,on_onset,on_offset,NULL);/* 3. 启动内部模型消费线程 */snore_detect_start(det);/* 4. 分块送入 PCM; 实时录音时改在录音回调里 feed */for(pos=0;pos<num_samples;pos+=FEED_CHUNK){intn=num_samples-pos;if(n>FEED_CHUNK)n=FEED_CHUNK;snore_detect_feed(det,pcm+pos,n);}/* 5. 停止并销毁 */snore_detect_stop(det);snore_detect_destroy(det);free(pcm);return0;}编译与运行(示例):
$(CC)snore_demo.c -I. -L.-lsnoredetect-lpthread-lm-osnore_demo ./snore_demo结语
鼾声识别的价值,是把整夜的呼吸事件变成可读的健康数据,需要时还能给出真实的干预。做睡眠监测、智能床垫或止鼾设备的团队,可以先用一段整夜录音试出端侧鼾声识别的效果。
在线验证:上传自己的录音,在线鼾声识别测试
代码下载:gitee下载,github下载
其它声音处理方面程序:
哭声识别:
面向边缘设备的离线嵌入式哭声检测
狗叫声识别:嵌入式离线犬吠检测 SDK 与分级告警
猫叫声识别:嵌入式离线猫叫声检测与宠物健康