第15章 音乐可视化(《Python趣味创意编程》教学视频) - 知乎

2020/12/09 09:34
阅读数 162

(图书介绍:童晶:《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) # 绘制椭圆形眼眶    

Minim库也可以利用麦克风获取实时声音信号,读者可以尝试发出音量大小、音调高低不同的声音,观察音频的实时可视化效果。

player = minim.getLineIn() # 获取实时音频输入  

这一章主要学习利用Minim库进行音频信号的处理,实现了一种音乐可视化的效果。读者也可以借鉴之前章节的思路,实现更加酷炫的音乐可视化;利用音乐文件或实时音频信号,也可以用于不同互动艺术形式的实时参数调整。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部