adrielcafe / AndroidAudioConverter

Convert audio files inside your Android app easily. Supported formats: AAC, MP3, M4A, WMA, WAV and FLAC.
1.33k stars 253 forks source link

Convert pcm #16

Open TooLazyy opened 6 years ago

TooLazyy commented 6 years ago

Hi, im recording audio track in android with AudioRecord object instance. sample rate = 16 000, channel config = mono_in format = ENCODING_PCM_16BIT

I tried to convert recorded file into aac, m4a, flac. Every time conversion is failed. Is it actually possible to convert from poor pcm? P.S. recorded file extension .pcm (tried .ogg)

tehscott commented 6 years ago

In order to do this I first had to convert PCM to WAV, as follows (found somewhere on SO):

private int frequency = 44100;
private mBufferSize = AudioRecord.getMinBufferSize(frequency, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
private static final int RECORDER_BPP = 16;

private void copyWaveFile(String inFilename /*pcm file*/, String outFilename /*wav file*/) {
  FileInputStream in;
  FileOutputStream out;

  long totalAudioLen;
  long totalDataLen;
  long longSampleRate = frequency;
  int channels = 1;
  long byteRate = RECORDER_BPP * frequency * channels/8;

  byte[] data = new byte[mBufferSize];

  try {
    in = getActivity().openFileInput(inFilename);
    out = getActivity().openFileOutput(outFilename, Context.MODE_PRIVATE);
    totalAudioLen = in.getChannel().size();
    totalDataLen = totalAudioLen + 36;

    writeWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate);

    while(in.read(data) != -1){
      out.write(data);
    }

    in.close();
    out.close();
  } catch (FileNotFoundException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

private void writeWaveFileHeader(
    FileOutputStream out, long totalAudioLen,
    long totalDataLen, long longSampleRate, int channels,
    long byteRate) throws IOException {

  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) (channels * 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);
}