Converting 16BitPCM to .wav, after switching endianness, the .wav file plays backwards

心已入冬 提交于 2021-01-07 01:36:33

问题


I am trying to build an Android app that records PCM audio and exports it as a wav file.

It worked fine for 8BitPCM, but when I switched to 16BitPCM I got white noise.

I finally figured out it was the endianness of the byte array, but now, after converting from Little Endian to Big Endian, I get my audio crystal clear, but reversed!

Here is how I call the method:

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

and then that byte[] is appended to my .wav header here:

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

and.... 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, 0, 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];
    }

So weird that the audio sounds exactly right, but backwards.

If I remove the call to "convertLittleEndianToBig()" I am back to white noise static.

Thanks for any help. This is my first real project.


回答1:


I'm an idiot - 16 bits != a byte.

I was reversing the byte array when I should have been reversing a short array.

I ended up replacing LittleEndianToBig with:

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

and the write command with:

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

I'll clean it up, but that was the issue. My audio is correct now.



来源:https://stackoverflow.com/questions/65419076/converting-16bitpcm-to-wav-after-switching-endianness-the-wav-file-plays-bac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!