2014-09-03 4 views
2

오디오 파일에서 PCM 데이터를 찾는 코드를 작성했습니다. 이 데이터를 고속 푸리에 변환 알고리즘에 어떻게 적용해야합니까? 바이트 배열을 FFT 알고리즘에 적용하기 전에 고려해야 할 사항이 더 있습니까?피치 검출을 위해 WAVE PCM 바이트 배열을 FFT로 전달

public static void main(String[] args) throws FileNotFoundException, IOException { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    BufferedInputStream in = new BufferedInputStream(new FileInputStream("adios.wav")); 

    int read; 
    byte[] buff = new byte[1024]; 
     while ((read = in.read(buff)) > 0) 
     { 
      out.write(buff, 0, read); 
     } 
     out.flush(); 
     byte[] audioBytes = out.toByteArray(); 

     for(int i=0; i<audioBytes.length;i++){ 
      System.out.println(audioBytes[i]); 
     } 
} 
+0

첫 번째 코드는 adios.wav의 내용을 방금 배열에 저장했지만 코드를 숫자 배열로 성공적으로 변환 한 것은 아닙니다. 그러려면 파일 헤더를 먼저 읽은 다음 헤더 데이터 유형 (int, float, 8-16 비트) 및 최종 압축을 사용하여 파일 내용을 적절하게 디코딩해야합니다. 둘째, 사용하려는 FFT 클래스는 무엇입니까? 먼저 그것을 사용하려고 시도한 다음 그것이 어떻게 잘못되었는지 설명하십시오. – lCapp

답변

3

당신은 WAV 헤더를 생략하고 샘플과 같은 변환이 필요한 엔디안 당 16 비트 PCM 웨이브와 바이트 배열 예 -1과 1 사이의 값을 부동하는 PCM 샘플을 변환해야 (com.sun.media.sound.AudioFloatConverter에서) :

public float[] toFloatArray(byte[] in_buff, int in_offset, 
    float[] out_buff, int out_offset, int out_len) { 
     int ix = in_offset; 
     int len = out_offset + out_len; 
     for (int ox = out_offset; ox < len; ox++) { 
      out_buff[ox] = ((short) ((in_buff[ix++] & 0xFF) | 
         (in_buff[ix++] << 8))) * (1.0f/32767.0f); 
     } 
     return out_buff; 
    } 

이 후에는 FFT 분석에 사용할 수있는 float[]로 끝날 호출합니다.

이 작업을보다 쉽게하기 위해 JVM에는 AudioSystemAudioInputStream 클래스가 포함되어 있습니다.

Java 오디오 처리 라이브러리 인 TarsosDSP의 소스 코드에는 많은 예제가 있습니다. TarosDSP manual은 PCM 데이터와 실행 가능한 샘플 간의 관계를 설명합니다.

+0

이 메서드에 전달해야하는 값은 무엇입니까? 내 손에 가지고있는 유일한 가치는 바이트 배열 인'in_buff'입니다. 'int in_offset, float [] out_buff, int out_offset, int out_len'에 무엇을 전달해야합니까? – user3805160