![ae400b1cfb6263376be53fe4e2bbd3ec.png](https://i-blog.csdnimg.cn/blog_migrate/aad1e931eb1a52248eea4b9eef6ee9c8.jpeg)
(图书介绍:童晶:《Python趣味创意编程》新书预告)
本章我们将实现音乐可视化的效果,如图所示。首先学习Minim库的下载配置,并利用Minim库播放音乐文件、绘制音乐音量波形;然后将声音转换到频域,学习音乐频谱波形的绘制,并实现圆圈射线频谱波形的效果;最后添加射灯连线、变大变小的眼睛,并学习实时声音信号的输入。
知乎视频www.zhihu.com视频教程:
知乎视频www.zhihu.com最终代码:
add_library("minim") # 导入minim库
minim = Minim(this) # 创建minim对象
def setup():
global player,fft,fftScale # 全局变量
size(1000, 1000) # 画面大小
player = minim.loadFile("music2.mp3") # 读取音乐文件
player.loop() # 音乐循环播放
fft = FFT(player.bufferSize(), player.sampleRate()) # 变换到频域
fftScale = 50 # 显示放大倍数
colorMode(HSB) # HSB颜色模型
frameRate(30) # 设定帧率
def draw():
background(255) # 白色背景
fft.forward(player.mix) # 处理下一段音频信号
# 这一段频谱信号长度,高频部分信号能量较低就不考虑了
specLength = fft.specSize()/2
for i in range(specLength): # 对所有频谱信号遍历
# 当前频谱上信号强度,开根号,再乘以一个放大系数
ffti = sqrt(fft.getBand(i))* fftScale
basis = width/6 + 2*sin(0.5*i+frameCount) #内部圆半径周期变化
angle = map(i,0,specLength-1,-0.5*PI,1.5*PI) # 直线段对应角度
startX = width/2 + cos(angle)*basis # 直线起点x坐标
startY = height/2 + sin(angle)*basis # 直线起点y坐标
endX = width/2 + cos(angle)*(basis+ffti) # 直线终点x坐标
endY = height/2 + sin(angle)*(basis+ffti) # 直线终点y坐标
# 沿着圆周设定线条颜色色调
stroke(map(i,0,specLength-1,0,255),255,255)
strokeWeight(1.5) # 设定线条粗细
line(startX, startY, endX, endY) # 画出向外的一圈直线
if i%2==0: # 射灯画线减一半,防止绘制速度过慢
stroke(map(i,0,specLength-1,0,255),200,255,40) # 射灯连线颜色
strokeWeight(1) # 设定射灯线条粗细
# 计算在第几区域,角点和对面的区域不要连线,防止画面过乱
sector = i*4/specLength # 分成4个区域
if sector != 1:
line(0, 0, endX, endY) # 左上角发出的射线
if sector != 2:
line(width, 0, endX, endY) # 右上角发出的射线
if sector != 0:
line(0, height, endX, endY) # 左下角发出的射线
if sector != 3:
line(width, height, endX, endY) # 右下角发出的射线
average = 0 # 求出所有频谱信号强度的平均值
for i in range(specLength): # 对所有频谱信号遍历
ffti = sqrt(fft.getBand(i))* fftScale # 开根号,再乘以一个放大系数
average += ffti # 先求和
average = average/specLength # 求平均值
# 中间随音乐音量大小而变换的圆圈椭圆/眼睛
noStroke() # 眼珠圆圈不绘制线条
fill(frameCount%256, 130, 200) # 眼珠的填充色
circle(width/2,height/2,average*1.5) # 绘制眼珠圆圈
noFill() # 眼眶不填充
strokeWeight(3) # 眼眶线条粗细
stroke(frameCount%256, 130, 200) # 眼眶线条的颜色
ellipse(width/2,height/2,average*3,average*1.5) # 绘制椭圆形眼眶
![0c0fbe85e4606ceaf793086b9ed064f6.png](https://i-blog.csdnimg.cn/blog_migrate/3bb52a6c74f6e4feb2d0593a00b24a88.png)
Minim库也可以利用麦克风获取实时声音信号,读者可以尝试发出音量大小、音调高低不同的声音,观察音频的实时可视化效果。
player = minim.getLineIn() # 获取实时音频输入
这一章主要学习利用Minim库进行音频信号的处理,实现了一种音乐可视化的效果。读者也可以借鉴之前章节的思路,实现更加酷炫的音乐可视化;利用音乐文件或实时音频信号,也可以用于不同互动艺术形式的实时参数调整。