差分
このページの2つのバージョン間の差分を表示します。
次のリビジョン | 前のリビジョン 次のリビジョン両方とも次のリビジョン | ||
of:soundspectrogram [2019/04/20 11:05] – 作成 baba | of:soundspectrogram [2019/04/20 12:49] – baba | ||
---|---|---|---|
行 1: | 行 1: | ||
====== マイク入力をリアルタイムでサウンドスペクトログラムする ====== | ====== マイク入力をリアルタイムでサウンドスペクトログラムする ====== | ||
+ | {{ : | ||
ofのExampleにはFFTを利用したものがすでに存在しますが、このページでは周波数解析結果を時系列に | ofのExampleにはFFTを利用したものがすでに存在しますが、このページでは周波数解析結果を時系列に | ||
表示するいわゆるサウンドスペクトログラムのサンプルプログラムを掲載しておきます。 | 表示するいわゆるサウンドスペクトログラムのサンプルプログラムを掲載しておきます。 | ||
行 7: | 行 8: | ||
の三つをそれぞれ fbo を利用して描画しています。必要なFFTクラスは下記のファイルを使ってください。 | の三つをそれぞれ fbo を利用して描画しています。必要なFFTクラスは下記のファイルを使ってください。 | ||
- | * | + | * {{ :of:fft.zip |}}(FFT.cpp, |
+ | |||
+ | <WRAP group> | ||
+ | <WRAP half column> | ||
+ | ofApp.cpp | ||
+ | <code .cpp ofApp.cpp> | ||
+ | #include " | ||
+ | #include " | ||
+ | |||
+ | |||
+ | #define SAMPLING_RATE 44100 | ||
+ | // | ||
+ | void ofApp:: | ||
+ | |||
+ | ofSetFrameRate(60); | ||
+ | |||
+ | fbo.allocate(BUF_FRAME, | ||
+ | fbo_raw.allocate(ofGetWidth(), | ||
+ | fbo_fft.allocate(ofGetWidth(), | ||
+ | |||
+ | int bufferSize = BUFSIZE; | ||
+ | soundStream.listDevices(); | ||
+ | soundStream.setup(this, | ||
+ | 0, | ||
+ | 1, | ||
+ | SAMPLING_RATE, | ||
+ | bufferSize, | ||
+ | 4); | ||
+ | |||
+ | for( int i = 0; i < BUF_FRAME; i++ ){ | ||
+ | for( int j = 0; j < BUFSIZE; j++){ | ||
+ | buf_spectrogram[i][j] = 0; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | gui.setup(); | ||
+ | gui.add(gain.set(" | ||
+ | } | ||
+ | |||
+ | // | ||
+ | void ofApp:: | ||
+ | fbo.begin(); | ||
+ | ofClear(0); | ||
+ | { | ||
+ | // Draw Sound Spectrogram | ||
+ | int pos_start_x = 0; | ||
+ | int pos_start_y = BUFSIZE-1; | ||
+ | glBegin(GL_POINTS); | ||
+ | for( int i = 0; i < BUF_FRAME; i++ ){ | ||
+ | for( int j = 0; j < BUFSIZE; j++){ | ||
+ | ofSetColor(255, | ||
+ | glVertex2f(pos_start_x+i, | ||
+ | } | ||
+ | } | ||
+ | glEnd(); | ||
+ | } | ||
+ | fbo.end(); | ||
+ | |||
+ | fbo_raw.begin(); | ||
+ | | ||
+ | ofBeginShape(); | ||
+ | for(int i = 0; i < BUFSIZE; i++ ){ | ||
+ | ofVertex(ofGetWidth()*(i/ | ||
+ | | ||
+ | } | ||
+ | ofEndShape(); | ||
+ | fbo_raw.end(); | ||
+ | |||
+ | fbo_fft.begin(); | ||
+ | | ||
+ | ofBeginShape(); | ||
+ | for( int i = 0; i < BUFSIZE; i++ ){ | ||
+ | ofVertex(ofGetWidth()*(i/ | ||
+ | | ||
+ | } | ||
+ | ofEndShape(); | ||
+ | |||
+ | ofDrawBitmapString(" | ||
+ | for( int i = 0; i < BUFSIZE/2; i++ ){ | ||
+ | if( i%10 == 0 ){ | ||
+ | ofDrawBitmapString( | ||
+ | | ||
+ | | ||
+ | } | ||
+ | if( i%10 == 0 ){ | ||
+ | ofLine(ofGetWidth()*(i/ | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | } | ||
+ | fbo_fft.end(); | ||
+ | } | ||
+ | |||
+ | // | ||
+ | void ofApp:: | ||
+ | ofBackground(0); | ||
+ | ofSetColor(255); | ||
+ | ofDrawBitmapString(ofToString(ofGetFrameRate()), | ||
+ | |||
+ | ofNoFill(); | ||
+ | ofSetLineWidth(1.0); | ||
+ | |||
+ | // Draw Sound Spectrogram | ||
+ | fbo.draw(0, | ||
+ | |||
+ | // Draw Realtime FFT | ||
+ | fbo_fft.draw(0, | ||
+ | |||
+ | // Draw RawData | ||
+ | fbo_raw.draw(0, | ||
+ | |||
+ | |||
+ | ofDrawBitmapString(ofToString(spectrogram.size()), | ||
+ | gui.draw(); | ||
+ | |||
+ | } | ||
+ | |||
+ | void ofApp:: | ||
+ | { | ||
+ | if( key == ' | ||
+ | ofPixels pixels; | ||
+ | fbo.readToPixels(pixels); | ||
+ | ofSaveImage(pixels, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // | ||
+ | void ofApp:: | ||
+ | |||
+ | //lets go through each sample and calculate the root mean square which is a rough way to calculate volume | ||
+ | for (int i = 0; i < bufferSize; i++){ | ||
+ | sound[i] = input[i]; | ||
+ | } | ||
+ | |||
+ | float avg_power = 0.0f; | ||
+ | myfft.powerSpectrum(0, | ||
+ | (int)BUFSIZE/ | ||
+ | sound, | ||
+ | BUFSIZE, | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | & | ||
+ | |||
+ | for( int i = 511-1; i >= 0; i-- ){ | ||
+ | for( int j = 0; j < BUFSIZE; j++ ){ | ||
+ | buf_spectrogram[i+1][j] = buf_spectrogram[i][j]; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | for( int j = 0; j < BUFSIZE; j++ ){ | ||
+ | buf_spectrogram[0][j] = log10(power[j]); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP half column> | ||
+ | ofApp.h | ||
+ | <code .h ofApp.h> | ||
+ | #pragma once | ||
+ | |||
+ | #include " | ||
+ | #include " | ||
+ | #include " | ||
+ | |||
+ | #define BUF_FRAME 512 | ||
+ | #define BUFSIZE 512// 2^11 | ||
+ | |||
+ | class ofApp : public ofBaseApp{ | ||
+ | |||
+ | public: | ||
+ | void setup(); | ||
+ | void update(); | ||
+ | void draw(); | ||
+ | void keyPressed(int key); | ||
+ | |||
+ | void audioIn(float *input, int bufferSize, int nChannels); | ||
+ | ofSoundStream soundStream; | ||
+ | |||
+ | float sound[BUFSIZE]; | ||
+ | |||
+ | fft myfft; | ||
+ | float magnitude[BUFSIZE]; | ||
+ | float phase[BUFSIZE]; | ||
+ | float power[BUFSIZE]; | ||
+ | vector< | ||
+ | float buf_spectrogram[BUF_FRAME][BUFSIZE]; | ||
+ | double db_min; | ||
+ | |||
+ | ofxPanel gui; | ||
+ | ofParameter< | ||
+ | ofFbo fbo; | ||
+ | ofFbo fbo_raw; | ||
+ | ofFbo fbo_fft; | ||
+ | }; | ||
+ | |||
+ | </ | ||
+ | </ | ||
+ | </ | ||