振幅スペクトルのリアルタイム可視化

とある場所で振幅スペクトルのリアルタイム可視化をデモすることになったので、久しぶりにProcessingのプログラムを書きました。Minimに入っていた例をほぼそのまま使っています。(左右方向は20 Hz〜ナイキストを対数軸で、上下方向は-60〜0 dBを表示しています)

f:id:amarui:20170919152525p:plain

import ddf.minim.analysis.*;
import ddf.minim.*;

Minim minim;  
AudioPlayer jingle;
FFT fft;

void setup() {
  size(1024, 256, P3D);
  
  minim = new Minim(this);
  jingle = minim.loadFile("hogehoge.mp3", 1024);
  jingle.loop();
  
  fft = new FFT(jingle.bufferSize(), jingle.sampleRate());
}

void draw() {
  // set background color
  background(#0D2B36);  

  // compute FFT
  fft.forward(jingle.mix);
  
  // draw foreground
  stroke(#EEE8D5);
  strokeWeight(2);
  for(int i = 0; i < fft.specSize(); i++) {
    float y = fft.getBand(i) * 2.0 / fft.specSize();
    float xlog = log(float(i) / fft.specSize()) / log(10);
    float ylog = 20 * log(y) / log(10);

    // adjust x/y positions to fit into window
    xlog = (3.0 + xlog) / 3.0 * width;
    ylog = height - (ylog+60)/60 * height;

    // color based on amplitude
    stroke(color(255*ylog/height, 255*ylog/height*0.8, (255-255*ylog/height)*0.5));

    line(xlog, height, xlog, ylog);
  }
}

どれも1行〜2行の変更だけでできるので、楽しくてついつい必要以上のことをやってしまう。アレンジしだいで色々できるし、子どもの頃にこういうのがあったら無限にやってただろうな。(下のスクリーンショットは、周波数と振幅を極座標系で表示し、左右対称にコピーしたもの。蝶みたいに見える。)

f:id:amarui:20170919155040p:plain