yoppa.org


メディア芸術の基礎 2017 – 東京工科大学

第12回: 音響と映像の融合 – Processingで音を可視化する 1

この講義では、前半にProcessingを使用したインタラクティブなアニメーションの基本、後半はSonic Piを使用したサウンドプログラミングを行ってきました。今回はいよいよこの両者を融合して、音と映像を同時に用いた表現に挑戦していきたいと思います。

まず始めにProcessingを用いて音を視覚化する方法を検討します。単純に感覚的手法で視覚化するのではなく、音を周波数成分に分解しその変化を視覚的に表現します。ここでは、FFT(高速フーリエ変換)という手法を用います。

次に、この視覚化の手法を用いて、Sonic Piで作成してレコーディングした音をProcessingで読み込み、視覚化する方法について解説します。サウンドの解析には、Processingのコアライブラリである、Soundライブラリーを使用します。

スライド資料

サンプルコード

サウンドファイルの再生

//Soundライブラリーの読み込み
import processing.sound.*;
//サウンドプレイヤー
SoundFile soundfile;

void setup() {
  //サウンドファイルを読み込んでプレイヤーを初期化
  soundfile = new SoundFile(this, "sound.aiff");
  //ループ再生
  soundfile.loop();
}

void draw(){
}

マウスで再生スピードと音量を変化

//Soundライブラリーの読み込み
import processing.sound.*;
//サウンドプレイヤー
SoundFile soundfile;

void setup() {
  size(800, 600);
  //サウンドファイルを読み込んでプレイヤーを初期化
  soundfile = new SoundFile(this, "sound.aiff");
  //ループ再生
  soundfile.loop();
}

void draw() {
  background(0);
  //マウスのX座標で再生スピードを設定
  float rate = map(mouseX, 0, width, 0.0, 2.0);
  //マウスのY座標で音量を設定
  float amp = map(mouseY, 0, height, 1.0, 0.0);
  //再生スピードを適用
  soundfile.rate(rate);
  //音量を適用
  soundfile.amp(amp);
}

音量を円の直径に反映

//Soundライブラリーの読み込み
import processing.sound.*;
//サウンドプレイヤー
SoundFile soundfile;
//音量解析
Amplitude rms;

void setup() {
  size(800, 600);
  fill(0, 127, 255);
  noStroke();
  //サウンドファイルを読み込んでプレイヤーを初期化
  soundfile = new SoundFile(this, "sound.aiff");
  //ループ再生
  soundfile.loop();
  //音量解析を初期化
  rms = new Amplitude(this);
  //音量解析の入力を設定
  rms.input(soundfile);
}

void draw() {
  background(0);
  //音量を解析して値を調整
  float diameter = map(rms.analyze(), 0.0, 1.0, 0.0, width);
  //取得した音量で円を描く
  ellipse(width/2, height/2, diameter, diameter);
}

FFTによるスペクトラム表示

//Soundライブラリーの読み込み
import processing.sound.*;
//サウンドプレイヤー
SoundFile soundfile;
//オーディオデバイス
AudioDevice device;
//FFT(高速フーリエ変換)
FFT fft;
//FFTサイズ
int bands = 1024;
//グラフの高さのスケールを設定
float scale = 20.0;

void setup() {
  size(800, 600);
  fill(0, 127, 255);
  noStroke();
  //オーディオバッファーの設定
  device = new AudioDevice(this, 44000, bands);
  //サウンドファイルを読み込んでプレイヤーを初期化
  soundfile = new SoundFile(this, "sound.aiff");
  //ループ再生
  soundfile.loop();
  //FFTの初期化
  fft = new FFT(this, bands);
  fft.input(soundfile);
}

void draw() {
  background(0);
  //FFT解析実行
  fft.analyze();
  noFill();
  stroke(255);
  //線分の描画開始
  beginShape();
  //FFTのバンドの数だけくりかえし
  for (int i = 0; i < bands; i++) {
    //FFTの解析結果を高さにグラフを描く
    vertex(i * width/float(bands), height - fft.spectrum[i] * height * scale);
  }
  //線分の描画終了
  endShape();
}