打印
[RISC-V MCU 创新应用比赛]

沁恒 CH32V103 实现音乐频谱(多图预警)

[复制链接]
40990|71
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创#  @21小跑堂

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

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

  既然酷炫,那就办它

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

  音乐频谱怎么获取呢?

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

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



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

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

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

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

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

  移植,跑,duang duang duang  卡了

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

  就。。。

  就得换种思路继续了

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






















  单片机计算比较勉强,但是有 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吗?   

使用特权

评论回复
5
biechedan| | 2021-10-3 20:02 | 只看该作者
傅里叶变换速度怎么样   

使用特权

评论回复
6
wangdezhi| | 2021-10-3 20:02 | 只看该作者
有源代码可以参考吗?     

使用特权

评论回复
7
isseed| | 2021-10-3 20:03 | 只看该作者
VS1003B速度还可以?   

使用特权

评论回复
8
xietingfeng| | 2021-10-3 20:03 | 只看该作者
CH32V103计算效果怎么样   

使用特权

评论回复
9
suzhanhua| | 2021-10-3 20:03 | 只看该作者
这个界面做的 非常棒呢。   

使用特权

评论回复
10
mituzu| | 2021-10-3 20:04 | 只看该作者
音乐频谱的原理是什么?   

使用特权

评论回复
11
hellosdc| | 2021-10-3 20:04 | 只看该作者
使用的是几个点呢?     

使用特权

评论回复
12
uiint| | 2021-10-3 20:04 | 只看该作者
没有工程文件吗?   

使用特权

评论回复
13
hellosdc| | 2021-10-3 20:05 | 只看该作者

使用特权

评论回复
14
wonderfullook| | 2021-10-4 16:15 | 只看该作者
这个图形化界面用啥做的

使用特权

评论回复
15
sadicy| | 2021-10-4 16:54 | 只看该作者
我去,这也太牛了吧

使用特权

评论回复
16
rongwinzip| | 2021-10-6 20:14 | 只看该作者
大佬这是什么界面呢

使用特权

评论回复
17
trucyw| | 2021-10-8 14:12 | 只看该作者
好东西

使用特权

评论回复
18
zhengfish| | 2021-10-17 12:27 | 只看该作者
牛,这个能用RISCV实现。。。。。。。。。。。。。。

使用特权

评论回复
19
kkzz| | 2021-11-3 13:14 | 只看该作者
如何将单片机音乐频谱LED显示出来

使用特权

评论回复
20
hudi008| | 2021-11-3 13:14 | 只看该作者
求单片机音乐频谱程序  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

98

帖子

0

粉丝