2009-08-29 3 views
1

이 코드가 있지만 0에서 약 1050까지 임의의 주파수가 계속 반환됩니다. 왜 이런 일이 발생하는지 이해하도록 도와주십시오.FFT 문제 (임의의 결과 반환)

내 데이터 길이는 1024이고 샘플 속도는 8192이며 데이터는 마이크의 입력 데이터로 채워진 짧은 배열입니다.


float *iSignal = new float[2048]; 
float *oSignal = new float[2048]; 
int pitch = 0; 

for(x=0;x<=1024;x++) { 
    iSignal[x] = data[x]; 
} 

fft(iSignal,oSignal,1024); //Input data, output data, length of input and output data 

for(int y=0;y< 2048;y+=2) { 
if((pow(oSignal[y],2)+pow(oSignal[y+1],2))>(pow(oSignal[pitch],2)+pow(oSignal[(pitch)+1],2))) { 
     pitch = y; 
    } 
} 

double pitchF = pitch/(8192.0/1024); 
printf("Pitch: %f\n",pitchF); 

감사합니다,

니얼.

편집 : 코드가 변경되었지만 여전히 임의의 빈도가 반환됩니다. oSignal 가정

+0

무엇을 마이크에 제공합니까? 제가 말했듯이, 매우 순수한 음색이 아니라면 무작위적인 결과를 얻을 수밖에 없습니다. – avakar

+0

당신의 코드에서 동일한 피치 값으로 여러 번 계산되기 때문에 pow (oSignal [pitch], 2) + pow (oSignal [pitch + 1], 2)의 결과 값을 캐싱하여 코드를 약간 최적화 할 수 있습니다. – moala

+0

내 목소리와 기타 소리. 임의의 결과를 반환하지 않도록 제안 할 수 있습니까? 창 작업이 가능할까요? – Niall

답변

7

이 실제와 가상의 부품 교체, 그것은

for(int y=0;y< 8191;y++) 

for(int y=0;y< 8191;y+=2) 

에 편집을 변경하는 데 도움이 될 것으로, 같은 방식으로 복잡한 숫자로 가득 : 난하지 않았다 1024 샘플 만 전달한다는 것을 알 수 있습니다. 귀하의 경우에는 4096의 주파수 도메인 샘플만큼 많은 시간 영역 샘플을 전달해야합니다.

편집 : 한 가지 더 : 분명히 기본 주파수를 찾으려고합니다. 무언가가 컴퓨터 생성 톤 또는 인간 휘파람 인 경우 (둘 다 매우 순수한 톤임) 결과에 실망 할 수 있습니다. 당신이 간행 한 간단한 방법은 피리를 위해 간신히 작동합니다.

편집 : 음성 및 기타의 경우 운이 좋지 않습니다. 나는 a program 몇 시간 전에 주파수 도메인을 표시하고, 그것을 시험해보고, 문제를 보게 될 것이다. 관심이 있으시면 sources도 있습니다.

최종 편집 : 위키 백과 article on pitch detection을 읽을 수 있습니다. 시간 영역 접근법에 집중하십시오.

+1

avakar가 말한 두 번째로, 음악적 목적을 위해 (즉, 반음의 1/100 이내로) 오디오 녹음의 피치를 정확하게 감지하는 것은 FFT로는 기본적으로 불가능합니다. 왜냐하면 얻은 주파수 해상도는 FFT 창 크기에 비례하기 때문입니다 . 자동 상관은 이러한 목적에 더 적합한 기술입니다. – MusiGenesis

0

"0에서 약 1050까지 임의의 주파수"- 일반적인 오디오 신호는 주파수의 조합으로 구성되지 않습니까? 샘플 속도가 8192 Hz이므로 FFT가 최대 8192/2 = 4096 Hz를 감지 할 수 있습니다. 나는 당신이 많은 주파수의 조합을 볼 것이라고 기대할 것이다. 그러나 나는 그것들을 "랜덤"이라고 부르지 않을 것이다.

왜 놀랍니? 내가 놓친 게 무엇입니까?

1

iSignal은 무작위 데이터를 포함하고 있습니다. 0으로 설정하려고 할 수 있습니다. 데이터 길이가 1024 (또는 1025) 인 경우 왜 8192를 fft()로 전달합니까?

또한 정수 부분에서 정밀도가 약간 떨어집니다. 더블 피치 F = 피치/(8192.0/1024)로 변경하십시오.

fft 함수가 실제 또는 복합 입력 데이터를 기대합니까? 이 복잡한 데이터를 예상하고 경우에, 당신은 0

0

두 가지로 iSignal의 다른 모든 항목을 설정해야합니다 : 당신은 당신이 당신의 fft 기능을 제대로 사용하고 있는지

  • 있습니까?출력을 [R_1 I_1 R_2 I_2 ...]으로 구성된 복잡한 배열로 처리하지만 입력 배열을 구성한 것처럼 처리합니다 ([R_1 R_2 R_3 ... R_1024 I_1 I_2 ...]as Henrik says). 그런 다음 복합 파트는 초기화되지 않은 상태로 둡니다.
  • peak detection은 매우 원시적인데, 단일 기타 입력과 같이 간단한 입력을 위해해야합니다. 인간의 목소리와 함께 사용하려면 좀 더 정교한 방법을 원할 것입니다.

알려진 단순한 (즉, 순수한 사인) 신호를 입력으로 사용해 보았습니까?