阅读wav文件:Java vs Matlab

4
我正在尝试在Java和Matlab中读取.wav文件的数据,并保存为字节数组。
在Java中的代码如下:
 public byte[] readWav2(File file) throws UnsupportedAudioFileException, IOException {

     AudioFormat audioFormat;

     AudioInputStream inputAIS = AudioSystem.getAudioInputStream(file);
     audioFormat = inputAIS.getFormat();
     ByteArrayOutputStream baos = new ByteArrayOutputStream();

     // Read the audio data into a memory buffer.
     int nBufferSize = BUFFER_LENGTH * audioFormat.getFrameSize();


        byte[] abBuffer = new byte[nBufferSize];
        while (true) {

            int nBytesRead = inputAIS.read(abBuffer);

            if (nBytesRead == -1) {
                break;
            }
            baos.write(abBuffer, 0, nBytesRead);
        }

        byte[] abAudioData = baos.toByteArray();


        return abAudioData;
    }

在Matlab中,我正在使用wavread函数:
[Y, FS] = wavread('sound.wav', 'native');

但是我得到的结果不同。
在Java中,前20个字节:
53, 0, 19, 0, -71, -1, -80, -1, -99, -1, 10, 0, 87, 0, -69, -1, 123, -1, -77, -1

在matlab中:
53, 19, -71, -80, -99, 10, 87, -69, -133, -77, 38, 143, 13, -100, 39, 45, -52, -83, -82, 56

为什么Java中的每个第二个字节都为0或-1,而在Matlab中却没有?即使我跳过Java中的0和-1,Matlab中也会有-133,而Java中是123。为什么会不同?

文件是否为立体声?在此媒体页面上提供的“leftright.wav”文件的结果是什么?为了更快地获得更好的帮助,请发布一个SSCCE - Andrew Thompson
1个回答

5

Java返回给您的是16位有符号PCM数据。每个样本是16位,一个字节包含8位,因此每个样本在Java中跨越两个字节。Matlab返回给您的是直接由16位样本组成的数组。

基本上,这些数据是相同的。只是在内存中排列方式不同。

如果您希望更轻松地从Java中访问这些样本,可以进行一些位运算,例如:

int firstSample = (abAudioData[0]&0xFF) | (abAudioData[1]<<8);

使用java.nio缓冲区读取样本的另一种方法:

ByteBuffer bb = ByteBuffer.wrap(abAudioData);
bb.order(ByteOrder.LITTLE_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();

int firstSample = sb.get();

这得到了与Matlab代码相同的结果-完美。但现在我需要将这些数据转换为双精度数组以进行FFT处理。因为这些字节被存储为short,所以该怎么做呢? - Radek
1
我认为你需要一个老式的循环,遍历每个“short”并将它们转换为“double”... - Joni
但是,如果您将字节转换为双精度浮点数,则与将保存为短整型的字节转换为双精度浮点数时得到的结果不同。 - Radek
1
不,当然不需要。对于FFT,您需要将每个16位样本(在Java中为short)转换为double - Joni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接