[作品提交] 【平头哥RVB2601创意应用开发】声音图形化显示和简单识别(作品提交)

oxygen_sh   2022-6-19 17:59 楼主

一、项目背景

随着物联网技术发展,很多物联网应用开始尝试利用声音信息来扩展产品功能,提升产品的易用性。例如利用物联网进行声音监控,或利用语音命令操控设备等。在声音类的功能中,如果加入声音的图形化显示可以大大提高用户对声音的感知度。

CH2601是低功耗、高性能的面向物联网应用的高级MCU芯片。其功能特性、片上资源和运行频率等非常适合对音频数据进行处理。本项目使用CH2601实现声音采集,声音图形化显示,并对声音进行简单分析和识别。

 

二、作品简介

使用RVB2601板上的板载硅麦采集声音信号,采用直方图和频谱两种方式对声音进行图形化显示。直方图能显示出音频信号的时域信号强度。频谱通过FFT得到,能够显示出音频信号的频率特性。使用按键在两种显示之间进行切换。

在频谱分析的基础上,实现了对声音类型的简单识别,可识别出无声音(silent)、人声(voice)和音乐(music),并将识别结果显示在屏幕上。

image-20220619173928-1.png
image-20220619173928-2.png  

三、系统框图

image.png  

四、各部分功能说明和解析

程序主要分为以下几个模块:

  • 主函数(包括声音采集)
  • LVGL任务
  • DISPLAY任务
  • 按键处理

1. 主函数

主函数主要功能包括,板子进行初始化、创建LVGL任务、创建DISPLAY任务、持续采集音频数据、使用直方图或频谱数据更新显示缓冲区。程序流程见下图:

image.png  

1.1声音采集

RVK2601板上有音频采样ADC ES7210和MIC电路。ES7210的控制命令通过I2C接口发送,音频采样数据则通过I2S接口来传输。

image.png  软件包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的滑动显示。根据按键切换不同的显示页面,或检测到不同声音类型时,需要显示不同的内容:

  • AUDIO HISTOGRAM silent
  • AUDIO HISTOGRAM music
  • AUDIO HISTOGRAM voice
  • AUDIO SPECTRUM silent
  • AUDIO SPECTRUM music  
  • AUDIO SPECTRUM voice

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任务实现对音频采集数据进行处理,

  • 声音强度直方图数据
  • FFT处理
  • 声音类型识别

image.png  

3.1 直方图

直方图显示采用5X7像素块堆叠来实现,在两个相邻像素块之间留有1个像素的间隔。直方图显示占用屏幕下部48X128区域,每行有16个像素块,每列根据声音不同强度,最多有8个像素块。

image.png  数据处理中,将待处理的数据帧分成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结果,对声音进行简单识别。识别当前声音类型:

  • Silent:无声音/背景噪声,
  • Voice:人说话声音
  • Music:音乐声音

识别方法如下:

首先对每帧out数据按数据顺序分成高/中/低3个子序列,分别对三个子序列进行绝对值累加,累加值分别记为A,B和C。通过对不同场景下A,B,C数值大小的分析,得到简单的判断条件如下:

  • Silent:B < 50 && C < 50
  • Music:  A>300 && B>A/2 && C>100 或者 B>A && C >100
  • Voice:  其他

经过实验,Music能够跟其他两种情况较好区分。Silent情况偶尔会受偶然较大背景噪声干扰,而识别为Voice。应该可以通过进一步滤波来达到更好效果。

 

4. 按键处理

定义GPIO callback函数。

void gpio_pin_callback(csi_gpio_pin_t *pin, void *arg);

当PA11连接的KEY按下时,进行直方图显示。

当PA12连接的KEY按下时,进行频谱图显示。

 

五、作品源码

audio_spectrum.rar (9.65 MB)
(下载次数: 24, 2022-6-19 17:57 上传)

 

六、视频演示

5-1

 

七、项目总结

从3月底收到RVK2601评估板开始,项目历时了接近3个月时间。在对平头哥MCU开发平台的不断学习和探索中,逐步完成了项目功能模块的开发,直至将整个作品完成。虽然距离最初设定的目标还有一定距离,但能有目前的完成度,个人还是觉得挺满意的。期待以后参与更多的产品评估。

 

八、设计报告

 

 

 

 

本帖最后由 oxygen_sh 于 2022-6-19 18:31 编辑

回复评论 (7)

能完成任务已很赞了

哈哈,听到楼主的声音了

好像外部噪音不大

image.png  

 

点赞  2022-6-20 07:04

看着效果很不错啊!【SpeexDSP模块函数】是平头哥官方自带的库,还是第三方库?

点赞  2022-6-20 10:49

完成度不错,学习学习

点赞  2022-6-20 14:52
引用: wangerxian 发表于 2022-6-20 10:49 看着效果很不错啊!【SpeexDSP模块函数】是平头哥官方自带的库,还是第三方库?

是第三方库,不过已经集成到CH2601的SDK里了

点赞  2022-6-20 20:39
引用: oxygen_sh 发表于 2022-6-20 20:39 是第三方库,不过已经集成到CH2601的SDK里了

那挺不错的!他们移植好了,我们就不需要自己移植了。

点赞  2022-6-21 10:07

看起来很不错啊

点赞  2022-6-22 21:35
专业,学习了,这个完成度不错,效果也好。这个作品值得学习。
点赞  2022-6-24 10:51
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复