[RISC-V MCU 创新应用比赛] 沁恒 CH32V103 实现音乐频谱(多图预警)

[复制链接]
37078|50
手机看帖
扫描二维码
随时随地手机跟帖
gtbestom|  楼主 | 2021-9-8 22:49 | 显示全部楼层 |阅读模式
#申请原创#  @21小跑堂

  使用沁恒 CH32V103 + VS1003B 制作的 MP3 播放器已经完成了基本功能,剩下的就是添加一些锦上添花的功能,让它有更好的使用体验和更酷的效果

  其中音乐频谱由于有动态跳跃的效果,给音乐增加了不少动感

  既然酷炫,那就办它

  音乐频谱是什么呢?简而言之,就是音乐的各个频率段的强度

  音乐频谱怎么获取呢?

  第一步:采样喇叭输出,获取音频信号随时间变化的关系,也就是时域波形,例如交流电的正弦波

  第二步:对时域波形进行傅里叶变换,可以将时域波形转换为频域波形,例如交流电的频域波形,只有 50Hz 段强度大小,其他频率段强度都是 0

705656138c3d283820.png


  变换的结果就是获取每个频率段信号的强度,傅里叶变换算法在计算机上抽象为离散傅里叶变换(DFT: Discrete Fourier Transform)

  离散傅里叶变换计算有限频率点的信号强度大小,例如在 20Hz 到 20000Hz 人耳能分辨的频段,抽取 1024 点计算各个点的频率强度

  但离散傅里叶变换需要计算复数、需要进行大量乘法计算,这是单片机所无法完成的

  但在前辈们的努力下,提出了快速傅里叶运算(FFT: Fast Fourier Transform),极大的减少了运算量,让单片机也能完成少量点数的时域-频域变换

  有现成的算法,那?不客气了就

  移植,跑,duang duang duang  卡了

  由于需要不断读取内存卡 MP3 数据,传输 MP3 数据到解码器,刷新界面时间进度等,再加入大量计算,导致音频数据和界面卡顿

  就。。。

  就得换种思路继续了

  这里做了23点的频谱效果,先上效果图,再深入讲解

266576138c8d77f56a.png


403626138c90128336.png


72886138c93b3a41a.png


563196138c95a0aef2.png


695526138c97d6e57e.png


491336138c9a51b980.png



992436138c9cbb7bde.png


460746138c9e817132.png


59096138ca13ce88b.png


27466138ca2b40ada.png


  单片机计算比较勉强,但是有 VS1003 解码芯片,可别忘了,它是颗 DSP 芯片,算起来可比单片机快速省事

  VS1003 如何获取频谱数据呢?打补丁,写入插件

  根据官方手册,VS1003 最多可以完成 23 点频谱计算,每秒可以计算 5 到 20 次,妥了

  打补丁

void VS10xx_PatchSpectrum(void)
{
  u16 i;
  for(i=0; i<943; i++)
  {
    VS10xx_WriteReg(atab[i], dtab[i]);
  }
}


  获取频谱数据

void VS10xx_GetSpectrum(u16* buf)
{
  u16 i, bands, val;
  VS10xx_WriteReg(SCI_WRAMADDR, BASE+2);
                                              /* If VS1011b, one dummy ReadSciReg(SCI_AICTRL3); here*/
  bands = VS10xx_ReadReg(SCI_WRAM);           /* If VS1011b, use SCI_AICTRL3 */

//  printf("bands: %d\r\n", bands);

  VS10xx_WriteReg(SCI_WRAMADDR, BASE+4);
                                              /* If VS1011b, one dummy ReadSciReg(SCI_AICTRL3); here*/
  for (i=0;i<bands;i++)
  {
    val = VS10xx_ReadReg(SCI_WRAM);         /* If VS1011b, use SCI_AICTRL3 */
                                            /* current value in bits 5..0,  normally 0..31
                                                  peak value in bits 11..6, normally 0..31 */
    *buf++ = val & 0x3F;
//    printf("%d\r\n", val & 0x3F);
  }
}


  获取频谱数据后,进行刷新显示即可,这里采用 200ms 读取刷新一次频谱,效果不错,音频和界面都很流畅

void GUI_MP3_DrawSpectrum(u16 x, u16 y, u16* dat, u16 len)
{
  u16 i;
  for(i=0;i<len;i++)
  {
    GUI_SetPen(Color_RGB565(33,33,36));
    GUI_Fill_Rectangle(x+(i*4),y-32,3,32-dat[i]);
    GUI_SetPen(Cyan);
    GUI_Fill_Rectangle(x+(i*4),y-dat[i],3,dat[i]);
  }
}












使用特权

评论回复

相关帖子

flytianya2010| | 2021-9-29 13:59 | 显示全部楼层
强大,膜拜大佬!

使用特权

评论回复
gygp| | 2021-10-3 20:02 | 显示全部楼层
这个gui是什么?   

使用特权

评论回复
chenci2013| | 2021-10-3 20:02 | 显示全部楼层
使用的是FFt吗?   

使用特权

评论回复
biechedan| | 2021-10-3 20:02 | 显示全部楼层
傅里叶变换速度怎么样   

使用特权

评论回复
wangdezhi| | 2021-10-3 20:02 | 显示全部楼层
有源代码可以参考吗?     

使用特权

评论回复
isseed| | 2021-10-3 20:03 | 显示全部楼层
VS1003B速度还可以?   

使用特权

评论回复
xietingfeng| | 2021-10-3 20:03 | 显示全部楼层
CH32V103计算效果怎么样   

使用特权

评论回复
suzhanhua| | 2021-10-3 20:03 | 显示全部楼层
这个界面做的 非常棒呢。   

使用特权

评论回复
mituzu| | 2021-10-3 20:04 | 显示全部楼层
音乐频谱的原理是什么?   

使用特权

评论回复
hellosdc| | 2021-10-3 20:04 | 显示全部楼层
使用的是几个点呢?     

使用特权

评论回复
uiint| | 2021-10-3 20:04 | 显示全部楼层
没有工程文件吗?   

使用特权

评论回复
hellosdc| | 2021-10-3 20:05 | 显示全部楼层

使用特权

评论回复
wonderfullook| | 2021-10-4 16:15 | 显示全部楼层
这个图形化界面用啥做的

使用特权

评论回复
sadicy| | 2021-10-4 16:54 | 显示全部楼层
我去,这也太牛了吧

使用特权

评论回复
rongwinzip| | 2021-10-6 20:14 | 显示全部楼层
大佬这是什么界面呢

使用特权

评论回复
trucyw| | 2021-10-8 14:12 | 显示全部楼层
好东西

使用特权

评论回复
zhengfish| | 2021-10-17 12:27 | 显示全部楼层
牛,这个能用RISCV实现。。。。。。。。。。。。。。

使用特权

评论回复
kkzz| | 2021-11-3 13:14 | 显示全部楼层
如何将单片机音乐频谱LED显示出来

使用特权

评论回复
hudi008| | 2021-11-3 13:14 | 显示全部楼层
求单片机音乐频谱程序  

使用特权

评论回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则