2013-06-28 2 views
1

몇 가지 문제점을 발견했습니다. 실제로 readAudioInputStream. 아래의 프로그램은 바이트 배열을 출력하지만 바이트 배열이 오디오 일 경우 실제로는 심지어 알지도 못합니다. 따라서 바이트 배열은 오디오 웨이브입니다.AudioInputStream.read 메서드가 정확히 무엇을 반환합니까?

try { 
     if ((numBytesRead = audio_in.read(audioBytes)) != -1) {     
       numFramesRead = numBytesRead/bytesPerFrame;     
       totalFramesRead += numFramesRead;    
     } 
    } catch (Exception e) { 
     System.out.println("Had problems reading new content"); 
    } 

모든 그래서 일단,이 코드는 내게되지 않습니다 :

File fileIn; 
AudioInputStream audio_in; 
byte[] audioBytes; 
int numBytesRead; 
int numFramesRead; 
int numBytes; 
int totalFramesRead; 
int bytesPerFrame; 

try { 
     audio_in = AudioSystem.getAudioInputStream(fileIn); 
     bytesPerFrame = audio_in.getFormat().getFrameSize(); 


     if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) { 
      bytesPerFrame = 1; 
     } 

     numBytes = 1024 * bytesPerFrame; 
     audioBytes = new byte[numBytes]; 
     try { 
      numBytesRead = 0; 
      numFramesRead = 0; 
     } catch (Exception ex) { 
      System.out.println("Something went completely wrong"); 
     } 
    } catch (Exception e) { 
     System.out.println("Something went completely wrong"); 
    } 

과 다른 부분

, 나는이 일부 바이트를 읽어보십시오. 이것은 처음으로 오디오 파일을 읽으므로 웹 간 도움이되었습니다. (링크를 찾았습니다. Java - reading, manipulating and writing WAV files 유래, 알려진 것 나타내는 audioBytes의 바이트 무엇

질문은을, 소스가 44kHz의, 스테레오이기 때문에, 어딘가에 숨어 2 파도가있을 있나요? ?, 내가 바로 내가이 바이트에서 중요한 정보를 필터링 어떻게 생각

// EDIT

그래서 내가 추가하는 것은이 기능입니다 :

public short[] Get_Sample() { 
    if(samplesRead == 1024) { 
     Read_Buffer(); 
     samplesRead = 4; 
    } else { 
     samplesRead = samplesRead + 4; 
    } 
    short sample[] = new short[2]; 
    sample[0] = (short)(audioBytes[samplesRead-4] + 256*audioBytes[samplesRead-3]); 
    sample[1] = (short)(audioBytes[samplesRead-2] + 256*audioBytes[samplesRead-1]); 
    return sample; 
} 

갔지은 Read_Buffer()는 다음 1024 바이트 (또는 그 이하)를 읽고이를 audioBytes에로드합니다. 왼쪽에는 sample [0], 오른쪽에는 sample [1]이 사용됩니다. 그러나 나는 파도가이 표정에서 상당히 시끄 럽기 때문에 아직도 확실하지 않습니다. (편집 : 사용 된 WAV는 실제로 리틀 엔디안 바이트 순서를 사용하여 계산을 변경해야했습니다.)

+0

* "이 바이트에서 중요한 정보를 어떻게 필터링합니까?"* 오디오 입력 스트림의 단일 프레임에 실제로 포함 된 중요한 정보는 무엇입니까? –

+0

그 실제 샘플. 여기 스테레오이기 때문에 모든 샘플에 대해 2 개의 값을 가져야합니다. 맞습니까? –

+0

* "여기 스테레오이므로 모든 샘플에 대해 2 개의 값을 가져야합니다. 그렇습니까?"* 예. 그러나 16 비트 (44.1KHz 스테레오의 경우 일반적 임) 인 경우 프레임 당 4 바이트와 채널 당 2 바이트가 있습니다. –

답변

2

AudioInputStream read() 메서드는 원시 오디오 데이터를 반환합니다. AudioFormat를 돌려주는 getFormat()를 사용해 오디오 형식을 읽어 내기 전에, 데이터의 「구축」이 무엇인지 모릅니다. AudioFormat에서는 getChannels() 및 getSampleSizeInBits() 등을 사용할 수 있습니다. 이는 AudioInputStream이 알려진 형식으로 만들어 졌기 때문입니다.

샘플 값을 계산할 경우 기호로 다른 가능성이 있고엔디안 (16 비트 샘플의 경우)입니다.

  • 인코딩() : PCM_SIGNED, PCM_UNSIGNED ...
  • 가 bigEndian() : 참 또는 거짓보다 일반적인 코드 이 AudioFormat 객체를 사용하려면 데이터 버퍼에 대한 자세한 정보 를 얻을 수 AudioInputStream를에서 반환

이미 잘못된 샘플 건물을 발견했기 때문에 소리가 불안정해질 수 있습니다. 다양한 파일로 작업하는 경우 나중에 문제가 발생할 수 있습니다. 일부 형식에 대한 지원을 제공하지 않으면 AudioFormat을 확인하고 예외를 throw하십시오 (예 : javax.sound.sampled.UnsupportedAudioFileException). 그것은 당신의 시간을 절약 할 것입니다.

+0

그러나 헤더 데이터 또는 설명자 데이터가 반환되지 않습니다. 맞습니까? 그래서 파일의 첫 번째 샘플에 대해 (이 예제에서는) 4 바이트로 시작한 다음 4 바이트로 된 두 번째 샘플 등으로 시작합니다. 내가 알아야 할 모든 것은 바이트가 양측에 속해 있다는 것입니다. (바이트 1 & 2는 왼쪽, 3 & 4는 오른쪽) 그리고 두 비트를 "결합"하는 방법입니다. (저는 sampe = 256 * firstByte + secondByte를 계산할 것입니다.) –

+0

아마도 도움이 될 것입니다 : http://blog.bjornroche.com/2013/05/the-abcs-of-pcm-uncompressed-digital.html –

+0

예, 도움이되었습니다. ;) 나는 그것을 지금 가지고 있다고 생각한다. –

관련 문제