2011-01-07 5 views
4

웨이브 파일을 16 비트 PCM 형식으로 가지고 있습니다. byte[]에 원시 데이터가 있고 샘플을 추출하는 방법이 있는데,이를 푸리에 변환을 수행하려면 float 형식 (즉, float[])으로 사용해야합니다. 여기 내 코드가 있는데,이게 맞습니까? Android에서 작업 중이므로 javax.sound.sampled 등을 사용할 수 없습니다.올바른 방법으로 16 비트 PCM 웨이브 데이터를 float으로 변환합니다.

private static short getSample(byte[] buffer, int position) { 
    return (short) (((buffer[position + 1] & 0xff) << 8) | (buffer[position] & 0xff)); 
} 

... 

float[] samples = new float[samplesLength]; 
    for (int i = 0;i<input.length/2;i+=2){ 
    samples[i/2] = (float)getSample(input,i)/(float)Short.MAX_VALUE; 
    } 
+0

참조 : http://stackoverflow.com/questions/15087668/how -to-convert-pcm-samples-in-byte-array-as-the-range-of-the-range – Brad

답변

6

나는 비슷한 해결책을 가지고 있었지만 조금 깔끔했습니다. 내가 알고 있어요 불행하게도, 지금까지의 좋은 라이브러리 방법이 없다 : *이 짝수 바이트 당신은의 ByteBuffer API를 사용하려고 할 수 있습니다 낮은 바이트

private static float[] bytesToFloats(byte[] bytes) { 
    float[] floats = new float[bytes.length/2]; 
    for(int i=0; i < bytes.length; i+=2) { 
     floats[i/2] = bytes[i] | (bytes[i+1] << 8); 
    } 
    return floats; 
} 
+0

이것은 부호없는 PCM에서만 작동합니다. 그렇지 않으면 각 바이트 쌍에서 두 번째 바이트의 부호 비트를 마스킹해야합니다. – hertzsprung

+2

@hertzsprung : 서명 된 PCM의 경우 어떻게해야합니까? – user1599964

3

가정합니다. ()

2

hertzsprung이 표시된대로 jk. 서명되지 않은 PCM에서만 작동합니다. Android PCM16은 big-endian으로 서명되었으므로 two's complement으로 인코딩 된 잠재적 인 음수 값을 고려해야합니다. 즉, 상위 바이트가 127보다 큰지 여부를 확인하고 256을 곱하기 전에 먼저 256을 뺍니다.

private static float[] bytesToFloats(byte[] bytes) { 
    float[] floats = new float[bytes.length/2]; 
    for(int i=0; i < bytes.length; i+=2) { 
     floats[i/2] = bytes[i] | (bytes[i+1] < 128 ? (bytes[i+1] << 8) : ((bytes[i+1] - 256) << 8)); 
    } 
    return floats; 
}