一、项目背景
随着物联网技术发展,很多物联网应用开始尝试利用声音信息来扩展产品功能,提升产品的易用性。例如利用物联网进行声音监控,或利用语音命令操控设备等。在声音类的功能中,如果加入声音的图形化显示可以大大提高用户对声音的感知度。
CH2601是低功耗、高性能的面向物联网应用的高级MCU芯片。其功能特性、片上资源和运行频率等非常适合对音频数据进行处理。本项目使用CH2601实现声音采集,声音图形化显示,并对声音进行简单分析和识别。
二、作品简介
使用RVB2601板上的板载硅麦采集声音信号,采用直方图和频谱两种方式对声音进行图形化显示。直方图能显示出音频信号的时域信号强度。频谱通过FFT得到,能够显示出音频信号的频率特性。使用按键在两种显示之间进行切换。
在频谱分析的基础上,实现了对声音类型的简单识别,可识别出无声音(silent)、人声(voice)和音乐(music),并将识别结果显示在屏幕上。
三、系统框图
四、各部分功能说明和解析
程序主要分为以下几个模块:
1. 主函数
主函数主要功能包括,板子进行初始化、创建LVGL任务、创建DISPLAY任务、持续采集音频数据、使用直方图或频谱数据更新显示缓冲区。程序流程见下图:
1.1声音采集
RVK2601板上有音频采样ADC ES7210和MIC电路。ES7210的控制命令通过I2C接口发送,音频采样数据则通过I2S接口来传输。
软件包sdk_chip_ch2601(v7.4.3)中,音频采集输入和输出功能的API由codec模块提供。本项目中对ES7210采用的配置如下:
input_config.bit_width = 16;
input_config.sample_rate = 8000;
input_config.buffer = input_buf;
input_config.buffer_size = INPUT_BUF_SIZE;
input_config.period = 1024;
input_config.mode = CODEC_INPUT_DIFFERENCE;
采集功能函数csi_codec_process()放置在main函数的主循环里,持续调用。采集到的数据保存在repeater_data_addr数组中,该数组为全局变量。DISPLAY任务对repeater_data_addr数组中数据进行分析处理。
2. LVGL任务
LVGL任务的功能是使用LVGL图形库实现文字LABEL的滑动显示。根据按键切换不同的显示页面,或检测到不同声音类型时,需要显示不同的内容:
LABEL的配置如下:
label2 = lv_label_create(lv_scr_act(), NULL);
lv_label_set_long_mode(label2,LV_LABEL_LONG_SROLL_CIRC);
lv_obj_set_width(label2, 120);
lv_label_set_text(label2, "AUDIO HISTOGRAM silent");
lv_obj_align(label2, NULL, LV_ALIGN_CENTER, 0, -25);
另外,文字滑动显示的速度,可以通过lv_tick_inc()函数来调节。
3. DISPLAY任务
DISPLAY任务实现对音频采集数据进行处理,
3.1 直方图
直方图显示采用5X7像素块堆叠来实现,在两个相邻像素块之间留有1个像素的间隔。直方图显示占用屏幕下部48X128区域,每行有16个像素块,每列根据声音不同强度,最多有8个像素块。
数据处理中,将待处理的数据帧分成16组,分别计算每组数据的累加和。然后对数据进行归一化处理。
3.2 FFT
直接调用SDK包中的SpeexDSP模块函数进行FFT运算。考虑运行时间,FFT计算数据长度为256。FFT采用的配置如下:
#define MAX_FFT_SIZE 256
#define USE_KISS_FFT 1
#define FIXED_POINT
在DISPLAY任务中首先需要调用FFT初始化函数:
void * table = spx_fft_init(FFTLEN);
FFT运算之前,需要对数据进行处理。根据先前的设定,音频数据是16位。
需要对8位采集数据数组repeater_data_addr变换成16位音频数据。另外还要对音频数据进行偏移处理。本项目中,采用的偏移量为3192。
然后调用SpeexDSP函数执行FFT,
spx_fft(table,in,out);
其中,in为输入的16位带偏移的音频数据,out为FFT输出数据。
3.3 声音识别
基于FFT结果,对声音进行简单识别。识别当前声音类型:
识别方法如下:
首先对每帧out数据按数据顺序分成高/中/低3个子序列,分别对三个子序列进行绝对值累加,累加值分别记为A,B和C。通过对不同场景下A,B,C数值大小的分析,得到简单的判断条件如下:
经过实验,Music能够跟其他两种情况较好区分。Silent情况偶尔会受偶然较大背景噪声干扰,而识别为Voice。应该可以通过进一步滤波来达到更好效果。
4. 按键处理
定义GPIO callback函数。
void gpio_pin_callback(csi_gpio_pin_t *pin, void *arg);
当PA11连接的KEY按下时,进行直方图显示。
当PA12连接的KEY按下时,进行频谱图显示。
五、作品源码
六、视频演示
七、项目总结
从3月底收到RVK2601评估板开始,项目历时了接近3个月时间。在对平头哥MCU开发平台的不断学习和探索中,逐步完成了项目功能模块的开发,直至将整个作品完成。虽然距离最初设定的目标还有一定距离,但能有目前的完成度,个人还是觉得挺满意的。期待以后参与更多的产品评估。
八、设计报告
本帖最后由 oxygen_sh 于 2022-6-19 18:31 编辑
看着效果很不错啊!【SpeexDSP模块函数】是平头哥官方自带的库,还是第三方库?
完成度不错,学习学习
引用: wangerxian 发表于 2022-6-20 10:49 看着效果很不错啊!【SpeexDSP模块函数】是平头哥官方自带的库,还是第三方库?
是第三方库,不过已经集成到CH2601的SDK里了
引用: oxygen_sh 发表于 2022-6-20 20:39 是第三方库,不过已经集成到CH2601的SDK里了
那挺不错的!他们移植好了,我们就不需要自己移植了。