音(低音)に合わせてLEDを光らせてみた
昔,こんな動画を作りました.
内容は,再生中の音楽を高速FFTして,ある周波数帯が設定した閾値を超えたら,シリアル通信で信号を送信.
受け取った方は,LEDを点灯させるという感じです.
ソースを知りたいというお声を頂いたので書いておきます.
結構前に作ったので,結構忘れているもんですね・・・
参考にしたサイトのプログラムの丸パクリです・・・
参考サイトはこちら
import ddf.minim.analysis.*; import ddf.minim.*; import processing.serial.*; Serial myPort; int S_a1; Minim minim; //Minim型変数であるminimの宣言 AudioPlayer player; //サウンドデータ格納用の変数 FFT fft; //フーリエ変換用変数 void setup() { size(512, 512); stroke(0); // シリアル通信の初期化 myPort=new Serial(this,"COM3",9600); minim = new Minim(this); // LEDを光らす閾値 S_a1 = 65; // 解析する音楽 player = minim.loadFile("unfragment (Original Mix).mp3", 512); player.loop(); //FFTオブジェクトを作成。bufferSize()は1024、sampleRateは初期設定では44100Hz。 fft = new FFT(player.bufferSize(), player.sampleRate()); println("sampling reate is " +player.sampleRate()); println("spec size is " +fft.specSize()); println("bandwidth is: " +fft.getBandWidth()); //最小単位の帯域 } void draw() { background(0); //fftを左と右の音声を混ぜて解析 //左右の音をそれぞれ取りたければ、player.left、player.rightという形で使う fft.forward(player.mix); // 周波数帯(86.133〜172.266)が閾値以上の時,シリアルでを送信 if (fft.getBand(1) > S_a1){ //background(255); myPort.write('1'); } else{ myPort.write('0'); } //サンプリングレートが44100Hzの場合、実際の周波数はその半分の0~22050Hzしか入っていない。 //なので、バッファサイズが1024だとすると、specSize()はバッファ/2 +1 になる。つまり513。 //また、バッファが1024ということは、44100Hzを1024分割していることになり、結果BandWidthは43.066406になる。 stroke(255); line(0,height-S_a1*4,width,height-S_a1*4); // 閾値ライン for(int i = 0; i < fft.specSize(); i++) { //画面のy座標の中心から上下に延びる線を描く if(i==1){ stroke(255,0,0); // 閾値判断用のスペクトルだけ色を変更する(赤) } else{ stroke(0,255,0); // 後は同じ色(緑) } float x1 = map(i,0,fft.specSize(),0,width); line(x1, height, x1, (height - fft.getBand(i)*4)); } } void stop() { // アプリケーションの終了前にAudioPlayerを終了する player.close(); // minimを終了 minim.stop(); //ソフト全体を終了 super.stop(); }
次にArduinoのプログラムです.こちらは,デフォルトで入っていたプログラムを元に作りました.
String txtMsg = ""; // 受信データ記録用 void setup() { // シリアル通信の初期化 Serial.begin(9600); pinMode(8, OUTPUT); } void loop() { // シリアル受信処理 while (Serial.available() > 0) { char inChar = Serial.read(); txtMsg += inChar; } if (txtMsg == '1') { digitalWrite(8, HIGH); // LED on } if (txtMsg == '0') { digitalWrite(8, LOW); // LED off } // 受信データ削除 txtMsg = ""; }