2013-06-28 68 views
1

我有一些问题发现,我实际上readAudioInputStream。下面的程序只是打印我得到的字节数组,但实际上我甚至不知道,如果字节实际上是样本,那么字节数组就是音频waveAudioInputStream.read方法返回什么?

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"); 
    } 

和其他部分,我读了一些字节,这样的:

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

所以首先,这个代码是不是从我这里。这是我第一次阅读音频文件,所以我从互联网上获得了一些帮助。 (发现链接: Java - reading, manipulating and writing WAV files 计算器,谁知道

的问题是,什么是代表audioBytes字节由于源是一个44kHz的立体声,也必须是2浪躲藏在那里的某个地方? ,我说的对让我怎么筛选重要信息这些字节

//编辑

所以我加入这个函数:??

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中。样本[0]用于左侧,样本[1]用于右侧。但我仍然不确定,因为我从这个看起来很浪漫。 (编辑:使用的WAV实际上使用little-endian字节顺序,所以我不得不改变计算。)

+0

*“那么如何过滤这些字节中的重要信息?”*您认为音频输入流的单帧实际上包含了什么确切的“重要信息”? –

+0

Tha实际样本。由于它是立体声,所以每个样本必须有2个值,对吗? –

+0

*“既然是立体声,那么每个样品必须有2个值,我是对的吗?”是的。但请注意,如果它是16位(典型值为44.1KHz立体声),则每帧将有4个字节,每个通道2个字节。 –

回答

2

AudioInputStream read()方法返回原始音频数据。在使用返回AudioFormat的getFormat()读取音频格式之前,您不知道数据的“构造”是什么。从AudioFormat中,你可以得到ChannelChannels()和getSampleSizeInBits()等等...这是因为AudioInputStream是为已知格式生成的。

如果计算样本值,您可能会遇到signes和 数据的字节顺序(在16位样本的情况下)。为了使一个更通用的代码 使用AudioFormat对象从返回的AudioInputStream以获得更多信息 有关数据缓冲区:

  • 编码():PCM_SIGNED,PCM_UNSIGNED ...
  • 大尾端():true或false

正如您已经发现不正确的样本建筑可能会导致一些干扰声音。如果您使用各种文件,将来可能会遇到问题。如果您不支持某些格式,只需检查AudioFormat并抛出异常(例如,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

是的,这有帮助。 ;)我想我现在明白了。 –