24元自制32段音乐频谱显示器
废话不多说,先上效果:
125fps高刷,HiFi级响应,专业级32段频谱显示
小时候特别流行组合音响,当初心目中的高档货必备的一台设备就是日本建武或JVC的多段均衡器。上面一定会有一个橙色或绿色的小窗,闪烁着迷人的光柱随着音乐跳动:
带实时频谱显示的JVC多段均衡器那时候把这东西叫做“太空窗”,当时只有真正高档的日本进口货才能看到这样的多段频谱显示。国产货实际上都是伪装得像是多段频谱的电平显示,效果那是差远了。所以估计像我这把年纪的大叔,应该都有那么一阵子非常向往这么个多段频谱窗。
不过虽然当年现实中的高档音响买不起,但是后来都在电脑上得到了满足——曾经必装的WinAMP 2的界面就是一台80年代末期最流行的组合音响:上面是黑胶机+磁带播放,中间是多段均衡器+功放,下面是唱片架(也就是界面上的播放列表)。当然,作为高档音响必备的频谱显示必须占据WinAMP界面上最显眼的位置:
WinAMP 2.0默认皮肤可惜后来的年轻人大多没经历过当年喇叭裤们扛着大收录机炸街、山寨组合音响家家K歌的时代。估计对这些东西毫无感觉,于是当年林林总总的频谱特效现在几乎都绝迹了。所以作为一个仍然怀旧的大叔,决定自己徒手撸一个来。
频谱显示的原理小时候是死活想不明白,后来大学里学了信号处理后才知道原来只要对音频信号做个快速傅立叶变换(FFT)即可。FFT算法可以快速计算出一个信号包含哪些频率的波形,以及这些波形的强度。所以一个在时域上看上去杂乱无章的信号波形(红色部分)在经过FFT后,就变成频域上几个频率处的振幅值(蓝色部分):
信号的时域频域变换对于文科生,你只要把FFT想成有一个听音大佬,听了一段琴声后就能说出它是由哪几个琴键分别是多少力度弹出来的:
FFT的本质:听音辨调所以只要有个东西不断地对麦克风传来的电压值进行采样,在采集一小段波形后算一把FFT得到每个琴键上的力度,再把这个力度画成柱状图就行了。这就是频谱显示的原理。
所以从硬件来看,这个频谱显示器要有三个主要部件:一个是单片机负责音频采样和快速傅立叶变换,一个是高灵敏度的麦克风用来接收外界声音,最后就是一个多段LED矩阵用来显示频谱柱状图了。
单片机我最初走了个弯路,先是选择了上海乐鑫的ESP8266,一块开发板只要7块8包邮。但是调试时发现这玩意的ADC数模转换器性能实在是太差了,采样极慢,精度也非常低,结果还有点薛定谔。于是只好改用9块9包邮的树莓派RP2040单片机,一试就发现这货ADC的性能实在是太给力了:精度高速度快,甚至实现96kHz高解析采样都毫无压力。看来以后做涉及模数转换类应用,选RP2040就对了:
祖国版的树莓派Pico这块RP2040就是从我之前做的黑猫警长相控阵火控雷达上拆下来的,因为娃早就玩腻了:
加购的外设主要是一颗带MAX4466前置放大器的麦克风(绿圈处可以用小螺丝刀调节放大器增益),3元一颗:
可调增益的麦克风以及这里面最贵的部件——11块5包邮的32x8点阵MAX7219单色红光LED矩阵:
面包板搭建的原型全部连起来就是上图这个样子,具体连线方式如下:
连线图上面树莓派RP2040的RESET开关选装,装上的话调试时会方便很多,不用老是插拔USB线。调完后就用不着了可以拔掉。对RP2040刷写程序的方式是按住BOOTSEL按钮不放,再按一下外接的RESET开关(或者拔插USB)最后松开BOOTSEL。这样RP2040会被识别为一个U盘,把编出来的固件拷进去再RESET一把即可。
软件编写过程略。。。这东西算法不难因为FFT什么的都有现成的库直接调用就行了。单片机只要循环不断地采样、算FFT、显示就行了,主要逻辑几分钟就能写好。难的是后面的频响校准和效果调试——反正和音响相关的调起来都是玄学。后来我折腾了半天给每个频段增加了一个内置均衡器把参差不齐的灵敏度拉齐,还写了一小段校准程序实现了均衡器自校准,最终得到了这样还算不错的扫频测试结果:
扫频测试结果
可以看到测试音频播放时,LED矩阵显示出了准确等高的音频频谱。这样在播放音乐时频谱就不会头重脚轻全部堆在中低频部分,而是会非常均匀的显示。另外采样频率上我也退到了24kHz。因为后来发现作为娱乐用的玩具蹦蹦跳跳的效果才是关键。采样频率低一点能丢掉实际播放时量极少几乎没显示的高频部分,而且低采样率带来的失真也给显示带来了一些随机性,更有趣味动感。48kHz采样虽然精准,但是显示效果干巴巴的,缺乏生动趣味。
总之在玄学的胡乱调校下,成品效果还算满意。刷新率能到125帧以上,响应速度非常灵敏丝滑(可惜视频无法拍出高刷效果):
125帧丝滑高刷配合我的15块钱闲鱼淘来的龙飞收音机,一边玩欧洲卡车模拟一边收听上海FM 101音乐广播,真是带劲极了:
五毛游戏装备氛围拉满
代码已在GitHub上开源。不过实际上如果你只想要个成品的话,花个三四十块也能直接在淘宝或者PDD买到类似成品,懒得折腾的可以试试。
源代码:https://github.com/megatops/arduino_toys/tree/main/spectrum
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~