java-带符号的16位PCM转换不起作用.为什么?

在过去的两天里,我一直试图在Android上操作16位PCM数据,但收效甚微.我目前正在使用WAV recorder捕获音频.在使用randomAccessWriter编写缓冲区之前,在onPeriodicNotification(AudioRecordrecorder)方法中,我将缓冲区发送到自定义类,以处理样本,并将样本保存回缓冲区中.我的自定义类中的方法如下:

由于缓冲区是一个字节数组,因此我首先将它们转换为短裤,现在一个短裤代表一帧(只有一个通道).一旦克服了这一障碍,我将实现FFT算法,该算法需要输入为float数组-因此我将每个short转换为float.现在,将数据写入WAV文件的randomAccessWriter接受一个字节数组,并期望每个帧为2个字节.因此,我将每个float转换回short并使用ByteBuffer重建一个字节数组,然后将其返回.当我运行记录器应用程序时,通过上述代码发送缓冲区,一切都很好.

我尝试使用简单的语音调制算法来测试录音是否被修改,该算法位于TODO注释所在的位置:

现在,如果我在iPhone上使用了上面的代码,则音频样本将被转换,尽管数据本来是32位浮点数.但是,在Android上,当我重新运行记录器应用程序并插入上面的代码时,产生的只是白噪声.在使用上述代码成功修改样本之前,无法继续进行FFT算法.

为什么会这样呢?如果有人对这个问题有一定的了解,我将不胜感激.

解决-比约恩·罗奇(Bjorn Roche)

潜在原因:记录是在Little Endian中提供数据,而Java短裤是Big Endian中的数据.当使用两种不同形式应用功能时,会产生白噪声.下面的代码显示了如何获取Little Endian字节数组,如何转换为Big Endian浮点数组以及如何返回Little Endian字节数组.在浮动时,您可以随心所欲地做任何事情,现在我将使用FFT算法:

public byte[] manipulateSamples(byte[] data,
                                int samplingRate,
                                int numFrames,
                                short numChannels) {

    // Convert byte[] to short[] (16 bit) to float[] (32 bit) (End result: Big Endian)
    ShortBuffer sbuf = ByteBuffer.wrap(data).asShortBuffer();
    short[] audioShorts = new short[sbuf.capacity()];
    sbuf.get(audioShorts);

    float[] audioFloats = new float[audioShorts.length];

    for (int i = 0; i < audioShorts.length; i++) {
        audioFloats[i] = ((float)Short.reverseBytes(audioShorts[i])/0x8000);
    }

    // Do your tasks here.

    // Convert float[] to short[] to byte[] (End result: Little Endian)
    audioShorts = new short[audioFloats.length];
    for (int i = 0; i < audioFloats.length; i++) {
        audioShorts[i] = Short.reverseBytes((short) ((audioFloats[i])*0x8000));
    }

    byte byteArray[] = new byte[audioShorts.length * 2];
    ByteBuffer buffer = ByteBuffer.wrap(byteArray);
    sbuf = buffer.asShortBuffer();
    sbuf.put(audioShorts);
    data = buffer.array();

    return data;

}

解决方法:

您的问题是Java中的短裤是bigendian,但是如果您从WAV文件中获取数据,则数据是little endian.

上一篇:win7中java编程工具安装 java环境变量设置


下一篇:JavaScript基础修炼(14)——WebRTC在浏览器中如何获得指定格式的PCM数据