2011-10-12 4 views
7

NAudio를 사용하는 오디오 플레이어가 있고 각 주파수 대역에 대해 실시간 강도를 표시하고 싶습니다.NAudio 주파수 대역 강도

I 이벤트가 1024 개 샘플의 각각의 블록에 대해 실행 된 경우 :

public void Update(Complex[] fftResults) 
{ 
    // ?? 
} 

것은 무엇 제가하고 싶은 것은, 각 주파수 대역의 강도를 나타내는 수치의 배열이다. 창을 16 개의 밴드로 나누고 싶습니다. 예를 들어

는 다음과 같이 수 많은베이스 주파수가 :

이 데이터와 가능하다면 내가 그 이벤트 처리기에 투입해야합니까
░░░░░░░░░░░░░░░░ 
▓▓▓░░░░░░░░░░░░░ 
▓▓▓░░░░░░░░░░░░░ 
▓▓▓▓░░░░░░░░░░░░ 
▓▓▓▓▓░░░░░░░░░░░ 
▓▓▓▓▓▓▓▓░░░▓░░▓░ 

?

오는 데이터 (Complex [])는 이미 FFT로 변환되었습니다. 스테레오 스트림입니다.

첫 번째 시도 :

double[] bandIntensity = new double[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 

    public void Update(Complex[] fftResults) 
    { 
     // using half fftResults because the others are just mirrored 
     int band = 0; 
     for (int n = 0; n < fftResults.Length/2; n++) 
     { 
      band = (int)((double)n/(fftResults.Length/2) * bandIntensity.Length); 
      bandIntensity[band] += Math.Sqrt(fftResults[n].X * fftResults[n].X + fftResults[n].Y * fftResults[n].Y); 
      bandIntensity[band] /= 2; 
     } 
    } 

위하고있다 뭔가하지만 난 너무 많은 처음 두 밴드로 간다 생각하고, 내가 그 많은 저음이없는 샤키라를 연주하고있다.

감사합니다.

답변

8

당신은 아마 여기에 해결하려는 두 개의 문제가 있습니다 :

(1) 윈도우 기능

당신은 그렇지 않으면 당신은 spectral leakage을 얻을 것이다는 FFT 이전 데이터에 window function을 적용해야하는 매우 얼룩진 스펙트럼을 초래할 것입니다. 스펙트럼 누출의 한 가지 불쾌한 부작용은 어떤 종류의 중요한 DC (0 Hz) 구성 요소가있는 경우 막대 그래프에서 볼 수있는 1/f 모양의 종류가됩니다.

(2) 로그 진폭/주파수

인간의 청각은 모두 강도 및 주파수 축에 필수적이다 대수 축. 뿐만 아니라 음성과 음악은 스펙트럼의 더 낮은 주파수 부분에서 더 많은 에너지를 갖는 경향이 있습니다. intensity와 intensity의 더 즐겁고 의미있는 디스플레이를 얻기 위해서 대개 magnitude와 frequency 축을 대수적으로 만듭니다. 이 축 크기의 경우 일반적으로 각 될 수있는, 당신은 아마 그룹 밴드에 당신의 쓰레기통에 좋습니다 축 주파수의 경우 즉, 전체 규모 재

magnitude_dB = 10 * log10(magnitude); 

을 dB를 음모에 의해 처리된다 1 옥타브 (2 : 1 주파수 범위), 또는보다 일반적으로 더 높은 해상도, 3 옥타브의 경우. 그냥 10 "바"를 원한다면 당신은 다음과 같은 옥타브 대역을 사용할 수 있습니다 :

25 - 50 Hz 
    50 - 100 Hz 
    100 - 200 Hz 
    200 - 400 Hz 
    400 - 800 Hz 
    800 - 1600 Hz 
1600 - 3200 Hz 
3200 - 6400 Hz 
6400 - 12800 Hz 
12800 - 20000 Hz 

(당신이 44.1 kHz의 샘플 레이트와 20 kHz에서의 오디오 입력 하드웨어에 상한이 가정).

강도 (magnitude) 스케일은 이러한 종류의 애플리케이션에 필수적이지만 로그 주파수 축은 덜 중요하므로 기존의 선형 비닝을 사용해 볼 수 있으며 어떤 영향을 주는지 알아보십시오 당신은 시간 영역에서 윈도우 함수를 적용하지 않고 (당신이 이미 가지고 있다고 가정하고) 크기 스케일을 dB로 변환합니다.

+1

당신은 내 영웅입니다. 롤. –

+0

윈도우의 경우 BlackmannHarrisWindow가 사용 된 것을 볼 수 있습니다. 그러나 나는 10xLog10()을 아직 시도하지 않았지만 그래프가 어떻게 바뀌는 지 보게됩니다. 그리고 0Hz DC bin을 제거합니다. –

+0

옥타브 빈을 콜렉션에 적용한 후에도 여전히 왼쪽에 너무 많은 별난 숫자가 있습니다 ... 나는 y 스케일을 dB로 변환했습니다. –