Writing PCM recorded data into a .wav file (java android)

后端 未结 4 491
别跟我提以往
别跟我提以往 2020-11-30 23:33

I\'m using AudioRecord to record 16 bit PCM data in android. After recording the data and saving it to a file, I read it back to save it as .wav file.

The problem is

相关标签:
4条回答
  • 2020-12-01 00:00

    I've been wrestling with this exact same question for hours now, and my issue was mostly that when recording in 16 bits you have to be very careful about what you write to the output. The WAV file expects the data in Little Endian format, but using writeShort writes it to the output as Big Endian. I also got interesting results when using the other functions so I returned to writing bytes in the correct order and that works.

    I used a Hex editor extensively while debugging this. I can recommend you do the same. Also, the header in the answer above works, I used it to check versus my own code and this header is rather foolproof.

    0 讨论(0)
  • 2020-12-01 00:00

    As Ronald Kunenborg correctly states the problem is the Litte Endian / Big Endian conversion.

    The simplest way is to write a short helper like this:

    public static void writeShortLE(DataOutputStream out, short value) {
      out.writeByte(value & 0xFF);
      out.writeByte((value >> 8) & 0xFF);
    }
    

    This is very helpful if you record audio to a wave file with Android and you're in need of the short array, too.

    (Credits: https://stackoverflow.com/a/1394839/1686216)

    0 讨论(0)
  • 2020-12-01 00:20

    Are you certain of the byte order? "RIFF", "WAV", "fmt", and "data" look fine but the numbers in the header may need to be a different order (little endian vs. big endian). You also don't need to convert to bytes manually using your intToByteArray method. You could use the writeInt and writeShort methods of DataOutputStream. For the first one, this would look something like:

    outFile.writeInt(Integer.reverseBytes((int)myChunkSize));

    For the shorts it'd be like:

    outFile.writeShort(Short.reverseBytes((short)myFormat))

    This way you also don't need to provide the offset and length (0, 4) numbers. It's nice.

    0 讨论(0)
  • 2020-12-01 00:24

    As per the header is concern, I had followed this code (if it's helps you some way).

    byte[] header = new byte[44];
    
            header[0] = 'R';  // RIFF/WAVE header
            header[1] = 'I';
            header[2] = 'F';
            header[3] = 'F';
            header[4] = (byte) (totalDataLen & 0xff);
            header[5] = (byte) ((totalDataLen >> 8) & 0xff);
            header[6] = (byte) ((totalDataLen >> 16) & 0xff);
            header[7] = (byte) ((totalDataLen >> 24) & 0xff);
            header[8] = 'W';
            header[9] = 'A';
            header[10] = 'V';
            header[11] = 'E';
            header[12] = 'f';  // 'fmt ' chunk
            header[13] = 'm';
            header[14] = 't';
            header[15] = ' ';
            header[16] = 16;  // 4 bytes: size of 'fmt ' chunk
            header[17] = 0;
            header[18] = 0;
            header[19] = 0;
            header[20] = 1;  // format = 1
            header[21] = 0;
            header[22] = (byte) channels;
            header[23] = 0;
            header[24] = (byte) (longSampleRate & 0xff);
            header[25] = (byte) ((longSampleRate >> 8) & 0xff);
            header[26] = (byte) ((longSampleRate >> 16) & 0xff);
            header[27] = (byte) ((longSampleRate >> 24) & 0xff);
            header[28] = (byte) (byteRate & 0xff);
            header[29] = (byte) ((byteRate >> 8) & 0xff);
            header[30] = (byte) ((byteRate >> 16) & 0xff);
            header[31] = (byte) ((byteRate >> 24) & 0xff);
            header[32] = (byte) (2 * 16 / 8);  // block align
            header[33] = 0;
            header[34] = RECORDER_BPP;  // bits per sample
            header[35] = 0;
            header[36] = 'd';
            header[37] = 'a';
            header[38] = 't';
            header[39] = 'a';
            header[40] = (byte) (totalAudioLen & 0xff);
            header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
            header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
            header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
    
            out.write(header, 0, 44);
    
    0 讨论(0)
提交回复
热议问题