2011-08-14 4 views
7

나는 Visualizer 클래스를 사용하여 android에서 오디오 스펙트럼 분석기를 구현하려고합니다.왜 FFT가 Windows Media Player와 다른 시각화 프로그램 출력을 제공합니까?

OnDataCaptureListener() 이벤트의 onFftDataCapture() 메서드에서 FFT 데이터를 얻고 있는데 캔버스에서 drawLines()을 사용하여 그릴 수 있습니다.

그러나 스펙트럼 표시가 제대로 표시되지 않습니다. 그래프의 왼쪽에서만 변화를 볼 수 있습니다. 그러나 Window Media Player에서는 같은 노래의 출력이 다릅니다. 내가 누락 된 것?

예제 나 링크로 누구에게 도움이 될 수 있습니까?

CODE mVisualizer는 비주얼 클래스 객체이며, mBytes는 FFT 데이터 onFftDataCapture 이벤트에서 가져온 것입니다

mVisualizer.setDataCaptureListener(
      new Visualizer.OnDataCaptureListener() { 

       public void onWaveFormDataCapture(Visualizer visualizer, 
         byte[] bytes, int samplingRate) {} 

       public void onFftDataCapture(Visualizer visualizer, 
         byte[] bytes, int samplingRate) { 
        mVisualizerView.updateVisualizer(bytes, samplingRate); 
       } 
      }, Visualizer.getMaxCaptureRate()/2, false, true); 

의 OnPaint()

for (int i = 0; i < mBytes.length/2; i++) { 
     mPoints[i * 4] = i * 8; 
     mPoints[i * 4 + 1] = 0; 
     mPoints[i * 4 + 2] = i * 8; 
     byte rfk = mBytes[2 * i]; 
     byte ifk = mBytes[2 * i + 1]; 
     magnitude = (float) (rfk * rfk + ifk * ifk); 
     int dbValue = (int) (10 * Math.log10(magnitude)); 
     mPoints[i * 4 + 3] = (float) (dbValue * 7); 
    }  
    canvas.drawLines(mPoints, mForePaint); 

.

이벤트 here에 의해 반환 된 FFT 데이터에 대해 자세히 읽을 수 있습니다.

이것은 내가 onFftDataCapture()을 얻을 값 것입니다 :

[90, -1, -27, 102, 13, -18, 40, 33, -7, 16, -23, -23, -2, -8, -11, -9, -8, -33, -29, 44, 4, -9, -15, -1, -2, -17, -7, 1, 1, 0, 3, -11, -5, 10, -24, -6, -23, 1, -9, -21, -2, 4, 9, -10, -14, -5, -16, 8, 6, -16, 14, 3, 7, 15, 10, -2, -15, -14, -5, 10, 8, 23, -1, -16, -2, -6, 4, 9, -1, 0, 0, 9, 1, 4, -2, 6, -6, -6, 8, -4, 6, 6, -4, -5, -5, -2, 3, 0, -1, 0, -7, 0, 2, 1, 0, 1, -1, 0, -1, 1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1]

어떤 생각, 링크가 도움이 될 것입니다.

Partial value drawing

full value drawing

@ 크리스 스트래튼은

지금은 square wave at 1000 Hz 파일을 재생하고의 스크린 샷을했다하고 업데이트

. 지금 뭐라고 하시겠습니까?

1 KHz spectrum

는 @ruhalde

가 지금은 Frequency sweep (20-20000 Hz) 파일을 재생하고 제안 및 출력 다음 생성 된이 파일 이후에 업데이트되었습니다.

Frequency sweep (20-20000 Hz) output

+0

스펙트럼을 다시 그릴 때마다 캔버스를 지우시겠습니까? 난 그냥 깨진 조각이 이전 무승부에서 남은 것 같아요 (격렬하게) ... –

+0

'updateVisualizer()'메소드에서'invalidate()'를 호출합니다. 그것은 그 일을하고 있습니다. –

+0

dB 및 크기 공식이 올바르지 않다고 생각합니다. 첫 번째 크기는 SQR (2)로 다중 타이핑하여 계산됩니다. 또한 dB 단위로 항상 한계 값으로 나눌 필요가 있습니다. 당신은 당신의 한계로 다이빙을하지 않으므로 당신의 한계는 1dB입니다, 그래서 당신의 그래프는 왜 이상한가. 여기에서 수식을 확인하십시오. http://zone.ni.com/devzone/cda/tut/p/id/4278 – ruhalde

답변

2

창 레퍼런스 및 안드로이드 응용 프로그램 모두에 알려진 크기의 사인 곡선을 연주하여 동작 (이유를 이해로 이어질 것입니다 희망) 예상과 다른 방법을 정확하게 파악하는 것이 유용 할 수 있습니다 개발중인. 한 번에 하나의 동기화 된 주파수를 테스트하고 각 화면에 그려지는 방식과 겉보기 크기의 위치, 크기 및 특이성을 확인하십시오.

예를 들어, 적용되는 주파수 범위의 차이를 발견하거나 선형 버전이 아닌 대수 축 (수십 또는 옥타브)에서 빈도를 그려야하는 버전이있을 수 있습니다.

데이터 소스가 마이크 인 경우 입력 회로 또는 설정에서 롤오프 할 수도 있습니다.

링크 된 문서는 어떤 창 기능이 사용되는지 설명하지 않습니다. 또한 Raw FFT 출력을 사용하면 인접 빈간에 에너지를 분산시킬 수 있으므로 각 지점을 인접한 두 개 또는 세 개의 평균으로 표시하는 일관된 결과를 얻을 수 있습니다.

+0

정보를 얻으려면 미디어 플레이어 용 스펙트럼이 필요하며 "알려진 크기의 정현파"제안을 시도 할 것입니다. –

+0

업데이트 된 게시물을 참조하십시오. –

+0

난 사각형 파도를 사용하지 않는 것이 좋습니다. 구형파의 주파수 스펙트럼이 어떻게 생겼는지 알고 있습니까? 즉, 흥미로운 것들을 볼 수 있습니다. 세 번째 피크는 내가 언급 한 인접 빈들 사이의 에너지 분담을 가지고 있습니다. 15KHZ를 약간 넘는 합리적인 응답을 얻은 것 같습니다. 아마 어딘가에 필터에서 일부 롤오프가 생겼을 것입니다. 약 10 KHz의 "구멍"은 흥미 롭습니다. 사인파의 주파수를 조정할 수있는 무언가를 설정하여 좀 더 자세히 조사해 볼 것을 제안합니다. 따라서 일정한 입력 크기의 시간에 하나의 주파수 만 가질 수 있습니다. –

2

나는 millihertz 따라 (

Visualizer.getMaxCaptureRate()/2 

최대 캡처 속도/2를 사용하는 필요, 그냥 초당 10에서 30 배 사이 어딘가에 값을 넣지 >> 주로 여기에 코드에서 일부 결함을 볼 수 있습니다 10000에서 30000 사이의 문서화), 이는 Visualizer 내부의 리소스에 너무 많은 압력을 가하지 않고 깜박 거리지 않을만큼 충분할 것입니다. 또한, 가청 스펙트럼 인 20 ~ 20Khz의 크기로 그려야합니다. 코드에서 0과 캡처 속도/2 사이의 모든 주파수를 그립니다. 최대 속도/2는 어떤 주파수가 더 높은 주파수인지 알고 있습니다. ..

그 외에도 순수한 사인파가 필요하며 압축률이없는 RAW 파일 인 경우 0 ~ 20Khz의 속도로 끊임없이 스윕하여 더 좋게 보입니다. 나는 어떤 OGG, MP3 또는 PCM 파일도 사용하지 않을 것이며, 압축되지 않은 WAV를 시도 할 것이고, harmonycs 때문에 미터로 스파이크를 많이 생성하는 구형파를 사용하지 않을 것입니다.

스윕 파일을 here if you want 에서 가져 오기 OnDataCaptureListener를 사용하여 getFft()를 폴링하는 대신 다른 스레드를 실행 해 보았습니까? RunOnUtiThread() 메소드로 UI를 업데이트하는 Runnable 내부에서이 접근법을 시도해 보겠다.

+0

범위 전체에 걸쳐 단일 주파수 입력을 테스트하는 것이 디버깅의 열쇠 일 수 있지만 자동 스위핑은 각 주파수에서 볼 수있는 것을 이해할 수있을 정도로 스윕이 느리지 않으면 분석하기 어려울 것입니다. 그런 다음 문제가있는 케이스는 꾸준한 입력으로 테스트해야합니다. –

관련 문제