搜索

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

[复制链接]
7926|0
手机看帖
扫描二维码
随时随地手机跟帖
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]);
  }
}












使用特权

评论回复

相关帖子

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

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

本版热帖

本版活跃用户

优质原创写原创,赢大奖

编辑推荐

  • 1 火星国务卿 得到打赏 ¥425.00
  • 2 yanzhengxin1 得到打赏 ¥350.00
  • 3 gaoyang9992006 得到打赏 ¥265.00
  • 4 Gavin3389 得到打赏 ¥225.00
  • 5 13426257085 得到打赏 ¥200.00
  • 6 呐咯密密 得到打赏 ¥185.00
  • 7 qbwww 得到打赏 ¥160.00
  • 8 两只袜子 得到打赏 ¥155.00
  • 9 yangjiaxu 得到打赏 ¥155.00
  • 10 elephant00 得到打赏 ¥150.00
在线客服 快速回复 返回顶部 返回列表