oxygen_sh 发表于 2022-6-19 17:59

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

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

<p><b>一、项目背景</b></p>

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

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

<p style="">&nbsp;</p>

<p><b>二、作品简介</b></p>

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

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

<p style=""><br />
&nbsp;</p>

<p><b>三、系统框图</b></p>

<p> &nbsp;</p>

<p><b>四、各部分功能说明</b><b>和解析</b></p>

<p>程序主要分为以下几个模块:</p>

<ul style="list-style-type: disc;">
        <li style="" value="50">主函数(包括声音采集)</li>
        <li style="" value="50">LVGL任务</li>
        <li style="" value="50">DISPLAY任务</li>
        <li style="" value="50">按键处理</li>
</ul>

<p><strong>1. 主函数</strong></p>

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

<p> &nbsp;</p>

<p><strong>1.1声音采集</strong></p>

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

<p align="justify"> &nbsp;软件包sdk_chip_ch2601(v7.4.3)中,音频采集输入和输出功能的API由codec模块提供。本项目中对ES7210采用的配置如下:</p>

<pre>
<code>    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;</code></pre>

<p align="justify">采集功能函数csi_codec_process()放置在main函数的主循环里,持续调用。采集到的数据保存在repeater_data_addr数组中,该数组为全局变量。DISPLAY任务对repeater_data_addr数组中数据进行分析处理。</p>

<p>&nbsp;</p>

<p><strong>2. LVGL任务</strong></p>

<p>LVGL任务的功能是使用LVGL图形库实现文字LABEL的滑动显示。根据按键切换不同的显示页面,或检测到不同声音类型时,需要显示不同的内容:</p>

<ul>
        <li style="" value="50">AUDIO HISTOGRAM silent</li>
        <li style="" value="50">AUDIO HISTOGRAM music</li>
        <li style="" value="50">AUDIO HISTOGRAM voice</li>
        <li style="" value="50">AUDIO SPECTRUM silent</li>
        <li style="" value="50">AUDIO SPECTRUM music &nbsp;</li>
        <li style="" value="50">AUDIO SPECTRUM voice</li>
</ul>

<p style="">LABEL的配置如下:</p>

<pre>
<code>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);</code></pre>

<p>另外,文字滑动显示的速度,可以通过lv_tick_inc()函数来调节。</p>

<p>&nbsp;</p>

<p><strong>3. DISPLAY任务</strong></p>

<p>DISPLAY任务实现对音频采集数据进行处理,</p>

<ul>
        <li style="" value="50">声音强度直方图数据</li>
        <li style="" value="50">FFT处理</li>
        <li style="" value="50">声音类型识别</li>
</ul>

<p> &nbsp;</p>

<p><strong>3.1 直方图</strong></p>

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

<p> &nbsp;数据处理中,将待处理的数据帧分成16组,分别计算每组数据的累加和。然后对数据进行归一化处理。</p>

<p>&nbsp;</p>

<p><strong>3.2 FFT</strong></p>

<p>直接调用SDK包中的SpeexDSP模块函数进行FFT运算。考虑运行时间,FFT计算数据长度为256。FFT采用的配置如下:</p>

<pre>
<code>#define MAX_FFT_SIZE 256
#define USE_KISS_FFT 1
#define FIXED_POINT</code></pre>

<p>在DISPLAY任务中首先需要调用FFT初始化函数:</p>

<pre>
<code>void * table = spx_fft_init(FFTLEN);</code></pre>

<p>FFT运算之前,需要对数据进行处理。根据先前的设定,音频数据是16位。</p>

<p style="">需要对8位采集数据数组repeater_data_addr变换成16位音频数据。另外还要对音频数据进行偏移处理。本项目中,采用的偏移量为3192。</p>

<p style="">然后调用SpeexDSP函数执行FFT,</p>

<pre>
<code>spx_fft(table,in,out);</code></pre>

<p>其中,in为输入的16位带偏移的音频数据,out为FFT输出数据。</p>

<p>&nbsp;</p>

<p><strong>3.3 声音识别</strong></p>

<p>基于FFT结果,对声音进行简单识别。识别当前声音类型:</p>

<ul>
        <li style="" value="50">Silent:无声音/背景噪声,</li>
        <li style="" value="50">Voice:人说话声音</li>
        <li style="" value="50">Music:音乐声音</li>
</ul>

<p style="">识别方法如下:</p>

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

<ul>
        <li style="">Silent:B &lt; 50 &amp;&amp; C &lt; 50</li>
        <li style="">Music: &nbsp;A&gt;300 &amp;&amp; B&gt;A/2 &amp;&amp; C&gt;100 或者 B&gt;A &amp;&amp; C &gt;100</li>
        <li style="">Voice: &nbsp;其他</li>
</ul>

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

<p style="">&nbsp;</p>

<p><strong>4. 按键处理</strong></p>

<p>定义GPIO callback函数。</p>

<pre>
<code>void gpio_pin_callback(csi_gpio_pin_t *pin, void *arg);</code></pre>

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

<p style="">当PA12连接的KEY按下时,进行频谱图显示。</p>

<p style="">&nbsp;</p>

<p><b>五、作品源码</b></p>

<p></p>

<p>&nbsp;</p>

<p><b>六、视频演示</b></p>

<p>c5c171e3f2a523d0cab1ecd9e8613d41<br />
&nbsp;</p>

<p><strong>七、项目总结</strong></p>

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

<p>&nbsp;</p>

<p><strong>八、设计报告</strong></p>

<p></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

Jacktang 发表于 2022-6-20 07:04

<p>能完成任务已很赞了</p>

<p>哈哈,听到楼主的声音了</p>

<p>好像外部噪音不大</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

wangerxian 发表于 2022-6-20 10:49

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

tonyhy1976 发表于 2022-6-20 14:52

<p>完成度不错,学习学习</p>

oxygen_sh 发表于 2022-6-20 20:39

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

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

wangerxian 发表于 2022-6-21 10:07

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

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

tobot 发表于 2022-6-22 21:35

<p>看起来很不错啊</p>

芯片老兵 发表于 2022-6-24 10:51

专业,学习了,这个完成度不错,效果也好。这个作品值得学习。
页: [1]
查看完整版本: 【平头哥RVB2601创意应用开发】声音图形化显示和简单识别(作品提交)