16BitPCM转.wav,切换字节序后,.wav文件向后播放

问题描述

我正在尝试构建一个记录 PCM 音频并将其导出为 wav 文件的 Android 应用。

它对 8BitPCM 工作正常,但当我切换到 16BitPCM 时,我得到了白噪声。

我终于弄清楚这是字节数组的字节序,但是现在,在从 Little Endian 转换为 Big Endian 之后,我的音频清晰了,但颠倒了!

这是我调用方法的方式:

byte[] inputByteArray = convertLittleEndianToBig(readToByte(input));

然后那个 byte[] 被附加到我的 .wav 头文件中:

        OutputStream os;
        os = new FileOutputStream(output);
        bufferedoutputstream bos = new bufferedoutputstream(os);
        DataOutputStream outFile = new DataOutputStream(bos);

        // Adding header here...

        outFile.write(inputByteArray);

convertLittleEndianToBig():

   public static byte[] convertLittleEndianToBig(byte[] value) {
    final int length = value.length;
    byte[] res = new byte[length];
    for(int i = 0; i < length; i++) {
        res[length - i - 1] = value[i];
    }
    return res;
}

和.... readToByte():

public static byte[] readToByte(File file) throws IOException,FileNotFoundException {
    if (file.length() < MAX_FILE_SIZE && file.length() != 0L) {
        ByteArrayOutputStream ous = null;
        InputStream ios = null;
        try {
            byte[] buffer = new byte[4096];
            ous = new ByteArrayOutputStream();
            ios = new FileInputStream(file);
            int read = 0;
            while ((read = ios.read(buffer)) != -1) {
                ous.write(buffer,read);
            }
        } finally {
            try {
                if (ous != null)
                    ous.close();
            } catch (IOException e) {
            }

            try {
                if (ios != null)
                    ios.close();
            } catch (IOException e) {
            }
        }
        return ous.toByteArray();
    }
    else {
    return new byte[0];
    }

太奇怪了,音频听起来完全正确,但倒退了。

如果我删除对“convertLittleEndianToBig()”的调用,我就会回到静态白噪声。

感谢您的帮助。这是我的第一个真正的项目。

解决方法

我是个白痴 - 16 位!= 一个字节。

当我应该反转一个短数组时,我正在反转字节数组。

我最终将 LittleEndianToBig 替换为:

public static short[] convertLittleBytesToBigShorts(byte[] value) {

    short[] shorts = new short[value.length/2];
    ByteBuffer.wrap(value).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);

    return shorts;
}

和写命令:

for (int i = 0; i < inputByteArray.length; i++)
        {
            outFile.writeShort(inputByteArray[i]);
        }

我会清理它,但这就是问题所在。我的音频现在是正确的。