역시 이미 있더군여.
다시 한글로 검색을 해보니 아래와 같은 포스팅을 찾았습니다.
나에게 필요한 모든 정보는 다 있군요. 이제 속이 좀 쉬원합니다.
링크 : http://sites.google.com/site/heavenlydesigner/workshop/sound-visualization-and-sonification/3ju
* FFT (Fast Fourier Transform)
Time Domain의 정보를 Frequency Domain으로 바꿔주는 수학적인 공식
1024 Samples ㅡ> FFT ㅡ> 512 Frequency Bins (0 Hz ~ SampleRate/2 Hz)
예)
SR = 44,100Hz
0 Hz ~ 22,050Hz (각 Frequency Bin들은 43Hz (22050 / 512)의 간격)
샘플의 수치가 높아지면 간격이 좁아져서 해상도가 좋아지지만 레이턴시가 커지기 때문에 적절한 값을 사용해야함
import ddf.minim.analysis.*;
import ddf.minim.*;
Minim minim;
AudioPlayer jingle;
FFT fft;
String windowName;
void setup()
{
size(512, 200);
minim = new Minim(this);
jingle = minim.loadFile("jingle.mp3", 2048); // 1024개의 프리퀀시빈을 얻음
jingle.loop();
fft = new FFT(jingle.bufferSize(), jingle.sampleRate());
textFont(createFont("SanSerif", 12));
windowName = "None";
}
void draw()
{
background(0);
stroke(255);
fft.forward(jingle.mix); // FFT를 사용
for(int i = 0; i < fft.specSize(); i++) // specSize - 몇개의 정보인지를 알려줌
{
line(i, height, i, height - fft.getBand(i)*4); // getBand - 각각의 프리퀀시 정보들을 얻어냄
}
fill(255);
text("The window being used is: " + windowName, 5, 20);
}
void keyReleased()
{
if ( key == 'w' )
{
fft.window(FFT.HAMMING);
windowName = "Hamming";
}
if ( key == 'e' )
{
fft.window(FFT.NONE);
windowName = "None";
}
}
void stop()
{
jingle.close();
minim.stop();
super.stop();
}
각 주파수 영역대별로 라인이 형성되는데 정상적인 음은 그 간격에 규칙성이 보이지만 노이즈에서는 그렇지 않음
Window에는 Hamming과 None 두가지 모드가 있음. Hamming을 사용하면 특정 주파수를 간섭없이 깨끗하게 뽑아냄
가장 이상적인 형태는 100Hz의 소리에서 100Hz 영역만 반응해야하지만 디지털 환경에서는 그렇지 못할 수 있음
한주기가 하나의 버퍼에 들어가지 못하고 짤리는 경우 원치않는 값이 얻어지게 될 가능성이 있음
그래서 하나의 짤린 하이 프리퀀시 주변에는 간섭되어지는 웨이브들이 발생함
Windowing을 통해서 각 버퍼에 진폭을 곱해주는 곡선을 하나 추가해서 좀 더 깨끗한 웨이브를 찾아냄
Hamming은 Windowing에서 추가하는 곡선 형태의 일종. Minim에서 제공하는 방식은 Hamming 한가지
타임 도메인에서의 getBand는 -1에서 1사이의 값을 가지지만 FFT에서는 매우 큰 값을 갖게 될 수도 있음
import ddf.minim.analysis.*;
import ddf.minim.*;
Minim m;
AudioInput jingle;
FFT fft;
float [] magList; // magnitude list
void setup()
{
size(512, 200);
m = new Minim(this);
jingle = m.getLineIn();
fft = new FFT(jingle.bufferSize(), jingle.sampleRate());
fft.window(FFT.HAMMING);
magList = new float[fft.specSize()];
}
void draw()
{
background(0);
stroke(255);
fft.forward(jingle.mix);
for(int i = 0; i < fft.specSize(); i++)
{
float v = fft.getBand(i);
if (magList[i] < v){
magList[i] = v;
}
else{
magList[i] *= 0.95;
}
line(i, height, i, height - magList[i]*4);
}
}
void stop()
{
jingle.close();
m.stop();
super.stop();
}


