문제

내가 사용하고 있는 fft(Fast Fourier Transform) 루틴을 이해하려고 노력 중입니다(훔치기)(재활용)

입력은 샘플 파형인 512개 데이터 포인트의 배열입니다.테스트 데이터가 이 배열에 생성됩니다.fft는 이 배열을 주파수 영역으로 변환합니다.fft 배열의 주파수, 기간, 샘플링 속도 및 위치 간의 관계를 이해하려고 합니다.예를 들어 설명하겠습니다.

========================================

샘플링 속도는 1000샘플/초입니다.10Hz에서 샘플 세트를 생성합니다.

입력 배열은 arr(28), arr(128), arr(228) ...에서 피크 값을 갖습니다.기간 = 100개 샘플 포인트

fft 배열의 최대 값은 인덱스 6에 있습니다(0의 큰 값 제외).

========================================

샘플 속도는 8000 샘플/s 440Hz에서 샘플 세트를 생성합니다.

입력 배열 피크 값에는 arr(7), arr(25), arr(43), arr(61) ...이 포함됩니다.기간 = 18개 샘플 포인트

fft 배열의 최대 값은 인덱스 29에 있습니다(0의 큰 값 제외).

========================================

fft 배열의 피크 인덱스를 주파수와 어떻게 연관시키나요?

도움이 되었습니까?

해결책

가상의 부분을 무시하면 주파수 분포가 빈을 가로 질러 선형입니다.

주파수@i = (샘플링 속도/2)*(i/nbins).

따라서 첫 번째 예제에서 256 개의 빈을 가지고 있다고 가정하면 가장 큰 빈은 1000/2 * 6/256 = 11.7Hz의 주파수에 해당합니다. 귀하의 입력은 10Hz이기 때문에 BIN 5 (9.7Hz)에도 큰 구성 요소가 있다고 생각합니다. 더 나은 정확도를 얻으려면 더 작은 쓰레기통을 얻으려면 더 많은 샘플을 가져 가야합니다.

두 번째 예제는 8000/2*29/256 = 453Hz를 제공합니다. 다시 말하지만, 더 가까이 있지만 더 많은 쓰레기통이 필요합니다. 여기서 해상도는 4000/256 = 15.6Hz입니다.

다른 팁

샘플 데이터 세트를 제공하는 경우 도움이 될 것입니다.

내 생각에 당신은 당신이 샘플링 아티팩트라고 불리는 것을 가지고있을 것입니다. DC의 강한 신호 (주파수 0)는 이것이 사실임을 시사합니다.

FFT를 호출하기 전에 입력 데이터의 평균 값이 0이 아닌지 항상 입력 데이터의 평균 값이 0인지 확인해야합니다.

같은 줄을 따라 샘플링 창 아티팩트에주의해야합니다. 샘플링 창 외부에서 내부로 "단계"가 다른 주파수에서 많은 에너지를 주입하는 효과가 있기 때문에 첫 번째 및 마지막 데이터 포인트는 0에 가깝습니다.

결론은 FFT 분석을 수행하려면 단순히 어딘가에서 발견 된 FFT 루틴을 재활용하는 것보다 더 많은주의가 필요하다는 것입니다.

다음은 질문에 설명 된 10Hz 신호의 첫 100 가지 샘플 포인트입니다. 샘플링 아티팩트를 피하기 위해 마사지

> sinx[1:100]
  [1]  0.000000e+00  6.279052e-02  1.253332e-01  1.873813e-01  2.486899e-01  3.090170e-01  3.681246e-01  4.257793e-01  4.817537e-01  5.358268e-01
 [11]  5.877853e-01  6.374240e-01  6.845471e-01  7.289686e-01  7.705132e-01  8.090170e-01  8.443279e-01  8.763067e-01  9.048271e-01  9.297765e-01
 [21]  9.510565e-01  9.685832e-01  9.822873e-01  9.921147e-01  9.980267e-01  1.000000e+00  9.980267e-01  9.921147e-01  9.822873e-01  9.685832e-01
 [31]  9.510565e-01  9.297765e-01  9.048271e-01  8.763067e-01  8.443279e-01  8.090170e-01  7.705132e-01  7.289686e-01  6.845471e-01  6.374240e-01
 [41]  5.877853e-01  5.358268e-01  4.817537e-01  4.257793e-01  3.681246e-01  3.090170e-01  2.486899e-01  1.873813e-01  1.253332e-01  6.279052e-02
 [51] -2.542075e-15 -6.279052e-02 -1.253332e-01 -1.873813e-01 -2.486899e-01 -3.090170e-01 -3.681246e-01 -4.257793e-01 -4.817537e-01 -5.358268e-01
 [61] -5.877853e-01 -6.374240e-01 -6.845471e-01 -7.289686e-01 -7.705132e-01 -8.090170e-01 -8.443279e-01 -8.763067e-01 -9.048271e-01 -9.297765e-01
 [71] -9.510565e-01 -9.685832e-01 -9.822873e-01 -9.921147e-01 -9.980267e-01 -1.000000e+00 -9.980267e-01 -9.921147e-01 -9.822873e-01 -9.685832e-01
 [81] -9.510565e-01 -9.297765e-01 -9.048271e-01 -8.763067e-01 -8.443279e-01 -8.090170e-01 -7.705132e-01 -7.289686e-01 -6.845471e-01 -6.374240e-01
 [91] -5.877853e-01 -5.358268e-01 -4.817537e-01 -4.257793e-01 -3.681246e-01 -3.090170e-01 -2.486899e-01 -1.873813e-01 -1.253332e-01 -6.279052e-02

그리고 다음은 FFT 주파수 영역의 결과적인 절대 값입니다.

 [1] 7.160038e-13 1.008741e-01 2.080408e-01 3.291725e-01 4.753899e-01 6.653660e-01 9.352601e-01 1.368212e+00 2.211653e+00 4.691243e+00 5.001674e+02
[12] 5.293086e+00 2.742218e+00 1.891330e+00 1.462830e+00 1.203175e+00 1.028079e+00 9.014559e-01 8.052577e-01 7.294489e-01

나는 수학 및 신호 처리에 대해서도 약간 녹슬었지만 추가 정보를 사용하면 촬영할 수 있습니다.

빈당 신호 에너지를 알고 싶다면 복잡한 출력의 크기가 필요합니다. 따라서 실제 출력 만 보는 것만으로는 충분하지 않습니다. 입력이 실수 일지라도. 모든 빈에 대해 출력의 크기는 pythagoras와 마찬가지로 sqrt (real^2 + imag^2)입니다.

빈 0 내지 449는 0Hz 내지 500Hz의 양의 주파수이다. 빈 500 ~ 1000은 음의 주파수이며 실제 신호의 양수와 동일해야합니다. 두 번째 주파수마다 하나의 버퍼를 처리하면 배열 지수가 잘 정렬됩니다. 따라서 인덱스 6의 피크는 6Hz와 일치하므로 약간 이상합니다. 이것은 실제 출력 데이터와 실제 및 가상의 데이터만으로도 인덱스 10에서 예상 피크를 제공하기 때문일 수 있습니다. 주파수는 빈에 선형으로 매핑되어야합니다.

0의 피크는 DC 오프셋을 나타냅니다.

내가 FFT를 한 지 얼마되지 않았지만 여기 내가 기억하는 것이 있습니다.

FFT는 일반적으로 복소수를 입력 및 출력으로 사용합니다. 따라서 입력 및 출력의 실제 부분이 어레이에 어떻게 맵을 맵핑하는지 잘 모르겠습니다.

나는 당신이하는 일을 정말로 이해하지 못합니다. 첫 번째 예에서 1000Hz의 샘플 속도에 대해 10Hz에서 샘플 버퍼를 처리한다고 말합니까? 따라서 각각 100 개의 샘플로 초당 10 개의 버퍼가 있어야합니다. 입력 배열의 길이가 228 개 이상인 방법을 알지 못합니다.

일반적으로 출력 버퍼의 전반부는 0 주파수 (= DC 오프셋)에서 1/2 샘플 속도로 주파수 빈입니다. 그리고 두 번째 절반은 음의 주파수입니다. 입력이 상상의 신호에 대해 0 인 실제 데이터 인 경우 양수 및 음수 주파수는 동일합니다. 출력에 대한 실제/가상 신호의 관계에는 입력 신호의 위상 정보가 포함되어 있습니다.

빈 I의 빈도는 i * (샘플 레테리아 / n)이며, 여기서 n은 FFT의 입력 창의 샘플 수입니다.

오디오를 처리하는 경우 피치가 주파수 로그에 비례하기 때문에 빈스의 피치 해상도가 주파수와 같이 증가하므로 저주파 신호를 정확하게 해결하기가 어렵습니다. 그렇게하려면 더 큰 FFT 창을 사용하여 시간 분해능이 줄어 듭니다. 주어진 샘플 속도에 대한 시간 분해능에 대한 빈도의 절충이 있습니다.

0 인 값이 큰 빈을 언급합니다. 이것은 주파수 0, 즉 DC 구성 요소가있는 빈입니다. 이것이 크면 아마도 당신의 값은 일반적으로 긍정적 일 것입니다. 빈 N/2 (귀하의 경우 256)는 샘플 속도의 절반 인 Nyquist 주파수이며,이 속도로 샘플링 된 신호에서 해결할 수있는 가장 높은 주파수입니다.

신호가 실제 인 경우, 빈 N/2+1에서 N-1은 각각 빈 N/2-1 내지 1의 복잡한 컨쥬 게이트를 포함합니다. DC 값은 한 번만 나타납니다.

다른 사람들이 말했듯이 샘플은 주파수 영역 (로그가 아님)에서 동일하게 간격을두고 있습니다.

예를 들어 1은 다음과 같습니다.

Alt Text http://home.comcast.net/~kootsoop/images/sine1.jpg

다른 예를 들어 있어야합니다

Alt Text http://home.comcast.net/~kootsoop/images/sine2.jpg

따라서 피크 위치와 관련하여 귀하의 대답은 모두 정확해 보입니다.

내가 얻지 못하는 것은 큰 DC 구성 요소입니다. 입력으로 사인파를 생성하고 있습니까? 입력이 음수가 되나요? 사인파의 경우 충분한 사이클을 얻으면 DC가 0에 가깝습니다.

또 다른 길은 a를 만드는 것입니다 Goertzel의 알고리즘 원하는 각 노트 센터 주파수 중

알고리즘의 하나의 구현이 작동하면 중심 주파수를 설정하는 데 매개 변수가 필요할 수 있습니다. 이를 통해 88 개를 쉽게 실행할 수 있습니다.

Goertzel 알고리즘은 기본적으로 단일 빈 FFT입니다. 이 방법을 사용하면 BINS 로그를 자연스럽게 진행하는 것처럼 BIN 로그를 배치 할 수 있습니다.

Wikipedia의 일부 의사 코드 :

s_prev = 0
s_prev2 = 0
coeff = 2*cos(2*PI*normalized_frequency);
for each sample, x[n],
  s = x[n] + coeff*s_prev - s_prev2;
  s_prev2 = s_prev;
  s_prev = s;
end
power = s_prev2*s_prev2 + s_prev*s_prev - coeff*s_prev2*s_prev;

이전 두 샘플을 나타내는 두 변수는 다음 반복을 위해 유지됩니다. 그런 다음 스트리밍 애플리케이션에 사용할 수 있습니다. 아마도 전력 계산이 루프 안에 있어야한다고 생각합니다. (그러나 위키 기사에서는 묘사되어 있지 않습니다.)

톤 감지 사례에서는 88 개의 서로 다른 성분이 있고 88 쌍의 이전 샘플이 있으며 88 개의 전력 출력 샘플이 발생하여 해당 주파수 빈의 상대 레벨을 나타냅니다.

WaveyDavey는 컴퓨터의 오디오 하드웨어를 통해 마이크에서 소리를 캡처하지만 결과가 0 중심이 아니라고 말합니다.하드웨어에 문제가 있는 것 같습니다.중심이 0이어야 합니다.

방이 조용할 때 사운드 API에서 나오는 값 스트림은 진폭이 0에 매우 가까워야 하며 주변 소음에 대한 약간의 +- 변화가 있어야 합니다.실내에서 진동음이 들리는 경우(예:피아노, 플루트, 음성) 데이터 스트림은 기본적으로 양수와 음수로 진행되고 평균이 0에 가까운 정현파 기반 파동을 표시해야 합니다.그렇지 않은 경우 시스템에 문제가 있는 것입니다!

-약간 뒤틀리게 하다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top