创意音频可视化效果,基于 p5.js 库以及使用 p5.sound 库来分析声音。

下面聊一下创建基本音频可视化效果的思路。

分析声音

当你想让绘图对音频信号做出反应时,你可以做的最基本的事情就是让它响应整个信号的音量和幅度。你可以根据这些特征制作一个基本的动画,如果你想要为低音和高音创建不同的动画,或者使用自定义频率范围来激活绘图的不同部分?Fast Fourier Transform 可以让你有更多选择。

FFT 是一个核心算法,可以分析波形并提供有关其不同频率的数据。因此,在音频轨道上运行FFT分析后,可以获得完整频谱和每个频率范围幅度的详细报告。然后,使用这些不同的范围幅度,可以使你的绘图对信号的低音,中音或高音进行不同的响应。

p5.sound 库有一个内置的FFT对象,它可以根据你的需求有很多有用的方法派上用场。对于本例,我们主要使用 getEnergy() ,它返回一个从0到255的值,表示该频率的音量。

在音乐播放过程中运行此分析,可以使视觉响应不同的频率!

// 初始化FFT对象
  var fft = new p5.FFT();

  // 在音频播放过程中运行分析
  fft.analyze();

  // 获取不同频率范围的值
  // -----------------------------------------------------
  // p5.sound 附带预定义的关键字 
  // 但 getEnergy() 中的数字不是关键字
  // 你可以自定义范围
  var bass    = fft.getEnergy( "bass" );
  var treble  = fft.getEnergy( "treble" );
  var mid     = fft.getEnergy( "mid" );     
  var custom  = fft.getEnergy( 100, 200 );

绘制 canvas

所有演示的思路可以概括为4个部分:

  • 创建一个初始绘图
  • 分析音频信号
  • 根据不同的频率范围为图形制作动画
  • 当鼠标移动时添加一些视觉交互

首先创建基础绘图,将一个圆分成几块,并在其周围绘制一些基本的形状。例如下面的演示图片中,可以将圆圈分成4部分,8部分等等(黑色线条代表每条线的反方向效果),则可以看到不同的效果。


  // 定义你想要划分圆的数量
  var pieces = 32;

  // 圆的半径
  var radius = 200;

  // 将原点移动到画布的中心
  translate( width/2, height/2 );

  // 居中圆圈
  stroke( 0, 0, 255 );
  ellipse( 0, 0, radius );

  // 为每部分画一条线
  for( i = 0; i < pieces; i++ ) {
    
    // 旋转原点
    rotate( TWO_PI / pieces );
    
    // 画红线
    stroke( 255, 0, 0 );
    line( 10, radius/2, 0, radius );
    
    //也可以画出相反的方向
    stroke( 0 );
    line( -10, radius/2, 0, radius ); 
  }

如果你使用动态数字切换这些静态变量,这些动态数字会随着时间而不断变化,例如特定频率的音量,低音,中音等,然后你可以运用这些值与你自定义的范围,来完全控制形状运动的动画。

// 运行 FFT 分析
  fft.analyze();

  // 获取不同频率范围的音量
  var bass    = fft.getEnergy("bass");
  var mid     = fft.getEnergy("mid");     
  var treble  = fft.getEnergy("treble");

  // 用你想要的数字映射每个音量的范围
  var mapBass     = map( bass, 0, 255, -100, 100 );
  var mapMid      = map( mid, 0, 255, -150, 150 );
  var mapTreble   = map( treble, 0, 255, -200, 200 );

  
  for( i = 0; i < pieces; i++ ) {
    
    rotate( TWO_PI / pieces );
    
    // 绘制低音线
    line( mapBass, radius/2, 0, radius );
    
    // 绘制中音线
    line( mapMid, radius/2, 0, radius );    

    // 绘制高音线
    line( mapTreble, radius/2, 0, radius );        
    
  }

你可以用你最爱的音乐,玩转不同的形状动画。

注:演示需要在服务器环境中运行。也可载入.mp4 文件。