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) # 绘制椭圆形眼眶