从声音到色彩:一个莫名其妙的开始
我得先说清楚,我搞这个“声音颜色”的东西,不是因为什么高大上的技术理想,纯粹是因为我被邻居家装修搞崩溃了。
那段时间我被强制在家远程办公,每天早上七点半,电钻准时开始唱摇滚。我被吵得心神不宁,代码写不下去。有一天中午,我把耳朵塞住,盯着桌上那个刚买的,带彩色跑马灯的廉价麦克风,心里突然冒出一个念头:这噪音如果非要有,能不能让它变得稍微好看一点?
我就想着,要是能把声音的频率实时转化成色彩,电钻声是不是就能变成一团让人惊悚的亮红色,而我自己的平静说话声,也许就是一抹舒服的蓝色或绿色。这想法很蠢,但我被噪音折磨得已经开始寻求玄学慰藉了。
抓取声音:把麦克风里的空气切成片
既然决定要干,那就马上动手。我这个人就是这样,想到什么就非得搞出来。我用了一个最不合适的工具——我以前做小游戏时用的那个引擎。我知道专业人士会用各种音频库,但那些东西太麻烦了,我只想用自己最顺手的烂工具。
第一步,我得把麦克风的声音“抓”进来。这个引擎在处理实时音频输入这块简直是噩梦。我花了一整个下午,翻了无数个外国论坛,才搞明白如何让引擎稳定地接收麦克风的输入,而不是一卡一卡的。我硬是熬着,把声音流像水管一样接到了程序里。
接进来后,声音还只是数据。我需要把这些连续的数据切开,看看里面到底有些什么。这就涉及到了频率分析。我没有用什么复杂的算法,就是找了个现成的简单库,去计算声音里面,哪种“高低音”占的比例最大。我把声音分成了三份:
- 低音区域(Bass):主要对应轰鸣感和低沉的声音。
- 中音区域(Mid):主要对应人说话的声音主体。
- 高音区域(Treble):主要对应尖锐的声音,比如电钻、高频啸叫。
我把这三份数据都用0到100的百分比记下来,作为我后续调色的基础。
色彩映射:从数据到眼睛能看的东西
接下来就是最折腾人的环节:如何让这些百分比变成颜色?
我一开始的思路是直接映射:低音强,就多加红色;高音强,就多加蓝色。结果一试运行,我的妈呀,屏幕闪得跟蹦迪现场一样,眼睛都要瞎了。我随便说一句话,颜色就从纯红跳到纯蓝,根本看不出任何规律,更别说“治愈”了。
我放弃了直接映射,转而采用了“笨办法”——平滑过渡。
我找了一个H S V(色相、饱和度、明度)的调色模型,这比直接调R G B要好控制多了。我重新设计了映射规则:
- 音量大小(整体振幅):直接控制明度(V)。声音越大,屏幕就越亮。电钻一响,屏幕瞬间白光一片,倒是挺符合实际感受的。
- 声音的“暖冷”:根据低音和高音的比例来控制色相(H)。我规定低音占比高,色相就偏红橙黄(暖色);高音占比高,色相就偏蓝紫青(冷色)。
- 声音的清晰度:用声音的复杂度来控制饱和度(S)。声音结构越复杂,色彩就越浓郁。
为了让它看起来不那么神经质,我加入了一个延迟和平滑处理,声音数据不是马上反馈,而是缓慢地在0.5秒内从旧颜色过渡到新颜色。这下,色彩变化就变得像水墨画一样流动起来,这才有了点“颜色”的样子。
最终实现:把色彩装进“游戏”里
这个程序运行时,它会在屏幕中间显示一个巨大的,不断膨胀和收缩的几何体,这个几何体的颜色和亮度,完全由我说话的声音控制。低声细语时,它是一团安静的深蓝色光晕;我大声吼叫时,它会瞬间变成一个刺眼的亮黄色球体,同时在屏幕上剧烈震动。
我搞定这一切,大概用了两天半的时间。虽然这玩意儿功能极其单一,但看着自己随口哼的一段旋律,在屏幕上变成一连串平滑过渡的色彩,那种感觉还挺美妙的。至少,我成功地把邻居的电钻声,转化成了我屏幕上规律闪烁的红色警告灯。
一步就是分享。我不能叫它“声音可视化工具”,那样太枯燥了。我直接把它打包成了一个极简的独立程序,命名就用了那个奇葩的标题。我说这是个“色彩游戏”,你下载下来,打开,对着麦克风说话或唱歌,玩玩你自己的声音颜色。虽然它不是一个真正的游戏,但这种自我实现和分享的快感,比写一万行代码有意思多了。
我的分享记录就是这样。用最笨的办法,最顺手的烂工具,去解决一个最无聊的问题。结果还真给我捣鼓出来一个可以运行的玩意儿,虽然粗糙,但是我的声音,终于有颜色了。