查看: 22|回复: 0

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

[复制链接]
  • TA的每日心情

    2024-11-15 16:19
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    292

    主题

    26

    回帖

    2978

    积分

    管理员

    积分
    2978
    发表于 7 天前 | 显示全部楼层 |阅读模式
    使用沁恒 CH32V103 + VS1003B 制作的 MP3 播放器已经完成了基本功能,剩下的就是添加一些锦上添花的功能,让它有更好的使用体验和更酷的效果

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

      既然酷炫,那就办它 undefined

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

      音乐频谱怎么获取呢?

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

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



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

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

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

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

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

      移植,跑,duang duang duang  卡了 undefined

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

      就。。。

      就得换种思路继续了

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






















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

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

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

      打补丁

    [url=]复制[/url]

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



      获取频谱数据

    [url=]复制[/url]

    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 读取刷新一次频谱,效果不错,音频和界面都很流畅

    [url=]复制[/url]

    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);
        GUI_SetPen(Cyan);
        GUI_Fill_Rectangle(x+(i*4),y-dat,3,dat);
      }
    }


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

    本版积分规则

    友情链接:

    返回顶部 返回列表