问题
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