Fake Plastic Trees

音楽とシステム,及び機械学習との関わりについてのサーベイや実装など.https://twitter.com/iwa_sheep

DAWから出力した音をフーリエ変換して可視化しつつ音も鳴らす

 

この記事は?

 この記事は,MIDIキーボードなどをDAWに接続しながら,Processingで音の可視化を行いつつ,音も出力するための手順を紹介します.

 

*また,この記事は,「PERSOL PROCESS & TECHNOLOGY Advent Calendar 2019」の最終日の記事です.

https://qiita.com/advent-calendar/2019/ppt

 

 

 

TL;DR

 

 今回のシステム構成を示します.ポイントは,複数出力装置で,音声へのアウトプットと,ループバックのためのsoundflowerへ出力しているところです.

 

システム構成図

システム構成図

 前提条件

 

目的と課題

 目的は,音を可視化しつつ音声を鳴らすことです.これにより,リアルタイムに演奏しながら音を可視化することができるため,演出パフォーマンスに利用できます.

 音をProcessingで可視化する方法は無数にありますが,今回はフーリエ変換した特徴量を利用します.Processingへ音を入力する方法は大きく分けて二つあり,

  1. マイクなどの入力装置を利用する
  2. PC上で鳴っている音を仮想的に出力 -> 入力(ループバック)させて利用する

です.今回は2の応用となります.

 2の方法を解説した記事は無数にありますが,課題として,ループバックさせてしまうので音が聞こえない(最終的にスピーカーに出力されない)というものがあります.実際にその問題は,この記事でも示唆されています.

qiita.com

 

対応策

 シンプルで,ループバックの入力と,スピーカーへの入力を同時に行うのみです.そんなこと可能なの?という感じですが,「複数出力装置」を利用することで簡単に実現できます.

 今回は,単純に音楽ファイルを再生するだけでは面白くないので,DAW経由で演奏しながら可視化しました.

 

複数入力装置の設定

1,Launchpadを開き「midi」と入力し,「Audio MIDI設定」をクリックする.

 

2,マスター装置に「Soundflower(2ch)」を設定し,下のリストからSoundflower(2ch)と,音を鳴らしたいスピーカー(Mac本体のスピーカーの場合は内蔵出力)の「使用」チェックボックスをチェックして下さい.

 

これで完成です.

これにより,アプリケーションのアウトプットに「複数出力装置」を選択すると,Soundflower(2ch)と内蔵出力の両方に出力されるようになります

すなわち,Processing側で,Soundflowerを入力として受け取ることにより,Processing側が受け取るシグナルと,スピーカーから出力される音が同期します.

 

DAW側の設定

 オーディオデバイスの出力先を,「複数出力装置」にするだけです.簡単ですね.

 画面はStudio Oneですが,CubaseだろうがPro Toolsだろうが一緒です.

例:Studio Oneの設定画面

 

デフォルトの入力デバイスの設定

 Processingではデフォルトの入力デバイスの音を受け取るように(デフォルトでは)なっているので,デフォルトの入力デバイスをSoundflowerに設定します.

 

1,右上のスピーカーアイコンをクリックし,"サウンド"環境設定を開く.

 

2,入力に「Soundflower(2ch)」を選択します.

 

これでDAWで発生した音が複数入力装置に出力され,

複数入力装置からスピーカーとSoundflowerに出力され,

Soundflowerからループバックされた音がProcessingに入力されるようになりました.

 

Processingのコード

下記記事の大部分を利用しています.

qiita.com

 

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

Minim minim;
AudioInput in;
FFT fft;

void setup() {
  size(1500, 800);
  background(255);

  minim = new Minim(this);
  //textFont(createFont("Calibri-Bold-24", 12));
  in = minim.getLineIn(Minim.STEREO, 512);
  fft = new FFT(in.bufferSize(), in.sampleRate());
  fft.window(FFT.HAMMING);
  stroke(255);
  frameRate(30);
  colorMode(HSB);
  strokeWeight(2);
}

void draw(){
  background(0);

  fft.forward(in.mix);

  for (int i = 0;i < fft.specSize() - 200; i++) {
    float x = map(i, 0, fft.specSize() - 200, 0, width);
    float h = map(i, 0, fft.specSize() - 200, 0, 255);
    stroke(h, 255, 255);
    line(x, height, x, height - fft.getBand(i) * 8);
  }
}


void stop() {
  minim.stop();
  super.stop();
}

 

結果

 

 

課題・展望

  • オケと演奏を同時に鳴らすと,リアルタイム感が無くなるMIDIを入力でも受け取れるので,オーディオ+MIDI情報を利用して,音のコード感やチャンネルなど離散的な情報を組み合わせることで面白くなりそう.
  • 構成が複雑なのでシンプルにしたい
  • DAW側で,複数入力装置をOutputに設定すると,なぜかInputも複数入力装置になってしまう.これだと,オーディオインターフェースからの入力を受け取れない.MIDI以外のアナログな楽器の入力を取れない. 

 

以上です.