I am trying to use AMR-WB encoding feature of Android Oreo to encode live microphone capture PCM using AudioRecorder. The encoding works without any exception but the encoded voice data seems not perfect. Here is how the code looks like:
My AudioRecord settings:
int audioSource = MediaRecorder.AudioSource.MIC;
int sampleRateInHz = 8000;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
AudioRecord ar = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSize);
MediaCodec settings:
MediaCodec mc = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AMR_WB);
MediaFormat mf = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AMR_WB, 4000, 1);
mf.setInteger(MediaFormat.KEY_BIT_RATE, 6600);
mc.configure(mf, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mc.start();
Recording loop:
int srcLength = ar.read(buffer, 0, bufferSize); // reads 640 bytes
int ibufferId = mc.dequeueInputBuffer(-1);
ByteBuffer ibuffer = mc.getInputBuffer(ibufferId);
ibuffer.position();
ibuffer.put(buffer, 0, srcLength);
mc.queueInputBuffer(ibufferId, 0, srcLength, 0, 0);
int obufferId = mc.dequeueOutputBuffer(bufferInfo, -1);
if (obufferId == INFO_OUTPUT_FORMAT_CHANGED) {
obufferId = mc.dequeueOutputBuffer(bufferInfo, -1);
}
ByteBuffer obuffer = mc.getOutputBuffer(obufferId); // has 18 bytes
mc.releaseOutputBuffer(obufferId, false);
If I write the output bytes (obuffer
) to file and try to play it using VLC player, it plays the audio faster than normal.
Is there any possible solution to this issue?
I found the answer myself. The source PCM sampling rate must be 16000 for legible AMR audio. I don't know why this is so.