2013-10-30 1 views
2

일부 매개 변수를 사용하여 AudioRecord에서 사운드를 녹음하기 시작합니다.안드로이드 - FFT를 계산 한 후에 주파수가 올바르지 않습니다.

private static final int RECORDER_SAMPLERATE = 44100; 
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO; 
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 
this.recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
      RECORDER_SAMPLERATE, RECORDER_CHANNELS, 
      RECORDER_AUDIO_ENCODING, this.bufferSize); 

데이터를 ArrayList에 저장합니다. < byte []> soundRecord;

while (this.isRecording) { 
    read = this.recorder.read(data, 0, this.bufferSize); 
    if (AudioRecord.ERROR_INVALID_OPERATION != read) { 
     try { 
      soundRecord.add(data); 
      os.write(data); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

이것은 내 사운드를 복잡한 배열 FFT로 계산하는 제 방법입니다. 그것을하기 전에, 나는 byte를 double로 변환한다.

public ArrayList<double[]> computeFFT(byte[] audioSignal) { 
    final int fftPoint = 65536; 
    ArrayList<double[]> result; 

    double tmp; 
    Complex[] y; 
    Complex[] complexAudioSignal = new Complex[fftPoint]; 
    double[] magnitude = new double[fftPoint/2]; 

    for (int i = 0; i < fftPoint; i++) { 
     if (i >= 22050) tmp = 0; 
     else tmp = (double) ((audioSignal[2 * i] & 0xFF) | (audioSignal[2 * i + 1] << 8)/32768.0F; 
     complexAudioSignal[i] = new Complex(tmp, 0.0); 
    } 

    y = FFF.fft(complexAudioSignal); 

    // Calculate magnitude values from fft[] 
    for (int i = 0; (fftPoint/2); i++) { 
     magnitude[i] = y[i].abs(); 
    } 

    // get only values over mid value 
    result = showFrequencies(magnitude, fftPoint); 
    return result; 
} 

내 문제는 피아노에서 440Hz로 일정한 사운드를 테스트합니다. "magnitude"내 피크를 얻을 수 있지만이 피크의 주파수는 220Hz입니다. 한 번만 (n 트랙을 사용하는) 샘플 사운드를 시도 할 때 주파수는 실제 주파수/2입니다.

주파수가 f = index * SAMPLE_RATE/fftPoint라는 것을 알고 있습니다.

누군가 나를 도울 수 있습니다. 당신이 제안처럼

내 전환 루프를 수정 : 나는


편집 한 ... 삼일 이후이 문제가 있습니다. 그것은 그렇게 보이는 것 : 문제는 지금 FrequencyIWant

int bytePerSample =2; 
int j = 0; 
for (int i = 0; i < audioSignal.length/2; i++) { 
    if ((i % 8 == 0 || i % 8 == 2) && i < 22050) { 
     tmp = (double) ((audioSignal[bytesPerSample * i] & 0xFF) | audioSignal[bytePerSample * i + 1] << 8))/32768.0F; 
     complexAudioSignal[j] = new Complex(tmp, 0.0); 
     j++; 
    } 
} 

입니다

= FreqIObtain/2 정말 지금 무엇을 해야할지하지 않습니다. '(

+0

2 분의 2에 지나지 않은 것으로 보입니다. 당신의 녹음은 인터리브 채널을 가진 스테레오인가요? 아니면 아마도 바이트 쌍 대신에 싱글 바이트를 샘플로 변환 했습니까? 실수로, 다른 문제들 중에서도 샘플 속도가 두 배라고 생각하는 것과 다소 비슷합니다. –

+0

의견을 보내 주셔서 감사합니다. 저는 오디오 초보자입니다. 이해가 안되/당신이하는 말을 알고 계십시오. 몇 가지 예를 들어 주시겠습니까? – BlackRabbit

+0

오디오 분석 프로젝트를 진행하기를 원하면이 주제를 이해하는 데 시간이 필요합니다. 그러나 스테레오 채널을 처리 할 의도가 없다면 소스 설정을 모노로 변경하십시오. –

답변

2

을 당신은에 두 개의 스테레오 채널을 복사하여 FFT, 왼쪽 또는 오른쪽 채널 대신 정수 풀기 및 변환 루프에서 4 바이트 중 2 개의 순차 바이트를 사용하십시오.

+0

감사합니다 !! 내 레코드를 AudioFormat.CHANNEL_IN_MONO로 변경합니다. 그리고 지금 저는 올바른 주파수를 가지고 있습니다. – BlackRabbit

+0

CHANNEL_IN_MONO를 사용하면 소리가 빠르며 값이 어리석은 것입니다. 내가 제안한 것을 어떻게 할 수 있습니까? – BlackRabbit

관련 문제