2011-01-06 1 views
3

나는 문제가있다. 자바에서는 wav 파일에서 샘플을 읽어야합니다. 파일 형식은 다음과 같습니다. wav, PCM_SIGNED, signed int of 2bytes = 16bits, little endian ... 개체가 BYTES에서 오디오 샘플을 읽고이 두 바이트를 하나의 double 값으로 변환해야합니다. 나는이 공식을 사용하려고하지만 완전히 정확하지입니다 :signed int (2 바이트, 16 비트)를 double 형식으로 변환합니다. Java로

mono = (double)((audioBytes[k] & 0xFF) | (audioBytes[k + 1] << 8)); 

난 항상 matlab에의 실제 값과 자바에서 변환 한 차이를 알 matlab에와 결과를 비교. 아무도 나를 도와 줄 수 있습니까? 감사합니다, Dave

+2

짧은 시퀀스의 예와 예상되는 출력의 예 및 실제 출력의 예가 있습니까? –

+0

audioBytes [k]가 byte이면 audioBytes [k] 및 0xFF == audioBytes [k]이므로 마스크는 쓸모가 없습니다. –

+0

audioBytes [k] == -1 인 경우 audioBytes [k] 및 0xFF == 255 (결과를 System.out.println에 전달한 후). –

답변

2

을 (변경 지수가 작은/큰 스왑) 당신은 matlab에 서로 다른 결과를 얻고있는 이유를 알고 우리에게 충분한 정보를 제공하지 않은 자바. 일반적으로 짧은 채널 데이터 [-32768..32767]을 [-1..1] 범위의 이중으로 스케일링하여 사용자가 시도하는 것처럼 보입니다. 귀하의 자바 결과 : -3.0517578125E-5 짧은 값 -1에 대한 올바른 : -1/32768. 나는 왜 당신의 Matlab 결과가 다른지 모르겠다. Matlab 결과에 어떻게 도달했는지 표시하지 않았습니다.

큰 순서의 바이트가 있다면 (내가 추측하고있는 것처럼), BIG-ENDIAN과 LITTLE-ENDIAN 또는 비트와 바이트를 이동하는 것에 대해 걱정하지 않으려면 Java에서 처리하도록하십시오. 당신이 :

import java.nio.*; 
... 
ByteBuffer buf = ByteBuffer.wrap(audioBytes); 
buf.order(ByteOrder.LITTLE_ENDIAN); 

while (buf.remaining() >= 2) { 
    short s = buf.getShort(); 
    double mono = (double) s; 
    double mono_norm = mono/32768.0; 
    ... 
} 

ByteBuffer.getShort() 버퍼의 다음의 2 바이트를 읽어, 리틀 - 엔디안 주문을 담당 짧은에 바이트를 변환하고, 다음의 getXXX() 호출에 대한 위치 자체를.

+0

이 방법이 가장 좋습니다. – Davide

+0

그러나 Matlab이 다른 결과를주는 이유는 아직 이해할 수 없습니다 ... – Davide

+0

MATLAB에서 실제로 수행하는 작업에 따라 다릅니다. 어떤 코드/명령을 실행하고 있습니까? ? –

-1

캔트 당신은 단지 most_significant 바이트 * 256 + least_significant_byte를하고 double로 캐스트 할 수 있습니까?

+0

이전에 설명 된 결과로 b [k] = - 1, b [k + 1] = - 1 Java의 바이트 값이 -128에서 127로 바뀌기 때문에 나는 그렇게 생각하지 않을 것입니다. –

+0

이것은 작동하지 않습니다. .. – Davide

0

이 올바른 방법입니다 :

double sampleValue = (double)((bytes[0]<<8) | (bytes[1]&0x00FF)); 

관련 문제