2009-06-05 2 views
4

나는 오디오 데이터를 처리하는 응용 프로그램을 만들고 있습니다. 자바 (나는 MP3SPI, Jlayer 및 Tritonus를 추가했습니다)를 사용하고 있습니다. .wav 파일의 오디오 데이터를 바이트 배열로 추출합니다. 필자가 작업하고있는 오디오 데이터 샘플은 16 비트 스테레오입니다. 나는 하나 개의 샘플의 형식을 읽은에 따르면.WAV 오디오 데이터 샘플을 double 유형으로 변환하는 방법은 무엇입니까?

은 다음과 같습니다

AABBCCDD AABB 왼쪽 채널과 CCDD rigth 채널 (각 채널에 대한 2 바이트)를 나타냅니다

. 이 샘플을 double 값 형식으로 변환해야합니다. 데이터 형식에 대해 읽었습니다. Java는 Big endian을 사용하고 .wav 파일은 little endian을 사용합니다. 나는 조금 혼란 스럽다. 전환 과정을 도와 주시겠습니까? 감사합니다 모두

답변

3

경고 : 정수와 바이트가 서명됩니다. 어쩌면 낮은 바이트를 함께 포장 할 때 마스크해야합니다.

for (int i =0; i < length; i += 4) { 
    double left = (double)((bytes [i] & 0xff) | (bytes[i + 1] << 8)); 
    double right = (double)((bytes [i + 2] & 0xff) | (bytes[i + 3] << 8)); 

    ... your code here ... 

} 
+0

좋은 지적이지만 모든 byte [] 액세스에서이를 수행해야합니다 (24 비트 이상 왼쪽으로 이동하지 않는 한). 그것들은 int로 승격되므로 0x80은 0xffffff80이됩니다. – erickson

+0

바로 그 것이고, 높은 바이트의 부호를 보존하고 싶습니다. 사실, 필자는 그것을 테스트하지 않았고 (특히 부동 소수점 값으로 작동하는지 모르겠다.) 서명 된 16 비트 값은 32 비트 이상으로 승격 될 때 부호를 잃어서는 안된다. –

+0

안녕하세요, 귀하의 답변에 감사드립니다. @erickson; 나는 당신의 의견을 정말로 이해하지 못합니다. @GB; 이렇게하면 왼쪽 채널의 각 샘플에 대한 값을 왼쪽으로 가져오고 오른쪽 채널에 대한 값은 오른쪽으로 가져옵니다. 결국, 각 샘플에 대해 2 개의 값을 가질 수 있습니까? 각 표본에 대해 하나의 값만 얻을 수 있습니까? – dedalo

0

Little Endian은 데이터가 BBAA 및 DDCC 형식임을 의미합니다. 당신은 단지 그것을 바꿀 것입니다. 프레임의 처음부터

:

int left = (bytes[i+1] << 8) + bytes[i]; 
int right = (bytes[i+3] << 8) + bytes[i+2]; 

내가 샘플 당신의 인덱스입니다

.

+1

- I 우선 순위가 약간 이상 할 수 있음을 기억하는 것 같습니다. –

+0

예, + - 교대조보다 편집 우선 순위가 높습니다. – CookieOfFortune

+1

이것은 하위 비트의 적절한 마스킹이 부족합니다. – erickson

0

저는 개인적으로 엔디안을 바꾸는 라이브러리를 찾습니다. UINT8

  • 16 비트 - - 24 비트
  • INT16 - INT32

    • 8 비트 : 당신이 권리를 얻는 것은 모든 비트 깊이에 대한 까다 롭다는/데이터 유형 파일 지원을 웨이브에 대한 각 오디오 파일 형식은 엔디안에 대한 가정을 가지고
    • 32 비트 - float로 INT32는
    • 32 비트 -
    • 64 비트 부동 - 더블을

    가장 일반적인 유형의 웨이브 파일을 지원하려면 이러한 모든 데이터 유형에 엔디안 변환이 필요합니다.

    나는 위에서 열거 한 대부분의 유형에 대해 byteswapping을 제공하는 ByteSwapper을 보았습니다.

    너무 나쁜 자바는 파일 IO 클래스에 엔디안 필드가 없습니다. 파일 크기가 크거나 작 으면 파일을 열 수 있다는 것이이 문제에 대한 훨씬 쉬운 해결책입니다.

    4

    ByteBuffer (java.nio.ByteBuffer)를 사용할 때 메서드 순서를 사용할 수 있습니다.

    [순서]

    공공의 ByteBuffer 마지막 ​​순서 (바이트 순서 보) 그 후

    Modifies this buffer's byte order. 
    
    Parameters: 
        bo - The new byte order, either BIG_ENDIAN or LITTLE_ENDIAN 
    Returns: 
        This buffer 
    

    수행 할 수와 전술 한 값을 얻는다;

    getchar가() getShort() 의 getInt() getFloat() getDouble()

    큰 어떤 언어 자바 ;-) 나는 개인적으로 교대 주위에 괄호를 넣어 것

    +1

    +1 +1 감사합니다. – Matt

    관련 문제