6

my project requires me to be able to record audio on an android device. i implemented solution using the MediaRecorder() but the recorded audio is in a terrible quality. what am i doing wrong? i must think that this cant be the only way to record audio :) perhaps i am doing something wrong, i am including my code below. please point me to the right direction.

thanks!

MediaRecorder recorder = new MediaRecorder();
File outputFile = new File(Environment.getExternalStorageDirectory(), "audio.3gp");
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(outputFile.getAbsolutePath());
recorder.prepare();
recorder.start();
// stop
recorder.stop();
recorder.reset(); 
recorder.release();
android-developer
  • 1,574
  • 4
  • 20
  • 27

5 Answers5

12

AMR_NB stinks.

Set the bitrate to 16 and sampling rate to 44100.

3gpp generally stinks, try using AAC/MPEG_4 instead.

Try this and update us.

keltor
  • 361
  • 1
  • 4
  • thanks, that worked :) i also used typo.pl's answer below but i cant mark them both as answers, can anyone help? – android-developer Feb 16 '11 at 04:25
  • Not sure how to help with that, but I can tell you that one SOME devices, you won't be able to get higher quality sound - it's apparently a chip limitation. There only seems to be a few devices like that mostly 1.5/1.6 limited ones. – keltor Feb 16 '11 at 06:09
10

The big problem I had in my audio recording quality was that I set the bit rate way too low at 16. 16 is a value that generally corresponds to bit depth, not bit rate. Bit rate is usually listed as kbps, but MediaRecorder.setAudioEncodingBitRate() take bps (note no "k"). Try this:

MediaRecorder recorder = new MediaRecorder();

recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(...);
recorder.setAudioEncoder(...);

final int bitDepth = 16;
final int sampleRate = 44100;
final int bitRate = sampleRate * bitDepth;

recorder.setAudioEncodingBitRate(bitRate);
recorder.setAudioSamplingRate(sampleRate);

recorder.setOutputFile(...);

recorder.prepare();
recorder.start();
// stop
recorder.stop();
recorder.reset(); 
recorder.release();

You'll need to check supported media formats to figure out the correct matchings of format (audio encoder), container (output format), sampling rate (usually given in kHz but passed to MediaRecorder.setSamplingRate() as just Hz), and bit rate (usually given in kbps). Note that not all formats in the documentation have specified bit rates; using the method in the code above should give a fair guess at the proper bit rate in that case.

Thanks to @StarPinkER, @PrvN, @arlomedia in this SO answer for helping me clear this up.

Community
  • 1
  • 1
Grant
  • 442
  • 5
  • 19
  • Worked for me, while above and accepted answer (just setting bitrate to 16 without multiplying) does not. Still has lots more ups, is this maybe phone related? I'm using an Samsung S7. –  Nov 21 '17 at 12:31
  • @RobinBetka 16 bps is ridiculously low to the point that it would be meaningless. Since the value of 16 yielded discernible audio even in my own tests, I assume that most libraries have some have some sort of sane lower limit on the bit rate that is passed into the codec. Depending on the device and the codec, I can easily see these lower limits being different. Thus, on some devices, the audio quality may be higher when the bit rate is specified as 16 in a different format because the lower limit in the new format is higher than the original format's default bit rate. Just a guess. – Grant Dec 04 '17 at 05:40
  • 1
    Your answer helped me, thanks. It seems, setting `bitRate = sampleRate * bitDepth` is important – Ildar Zaripov May 28 '18 at 13:45
  • 1
    Best and the only working Solution. The value for `setAudioEncodingBitRate()` was the most important part . +1 – Hissaan Ali Jul 03 '19 at 08:44
9

Try this code:

MediaRecorder recorder = new MediaRecorder();
File outputFile = new File(Environment.getExternalStorageDirectory(), "audio.3gp");
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setAudioEncodingBitRate(16);
recorder.setAudioSamplingRate(44100);
recorder.setOutputFile(outputFile.getAbsolutePath());
recorder.prepare();
recorder.start();

You are going to get some improvement but don't expect too much. You can always try to save uncompressed by using the RehearsalAudioRecord class from this OpenSource project

http://rehearsalassist.svn.sourceforge.net/viewvc/rehearsalassist/android/releases/RehearsalAssistant_0_8_2/src/urbanstew/RehearsalAssistant/

The way to implement the class into your project is very simple. You just need to replace your MediaRecorder by:

RehearsalAudioRecorder recorder = new RehearsalAudioRecorder(RehearsalAudioRecorder.RECORDING_UNCOMPRESSED, MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT);
recorder.setOutputFile(outputFile.getAbsolutePath());
recorder.prepare();
recorder.start();

You will be able to record WAVE files which are quite large but if you require quality is the only way to go. Please note that in older devices this code could

Julio Bailon
  • 3,735
  • 2
  • 33
  • 34
6

I've used the following settings and got very good audio results.

recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); recorder.setAudioEncodingBitRate(128000); recorder.setAudioSamplingRate(96000);

Andreas O.
  • 61
  • 1
  • 4
0

Without hearing the audio, I can't tell much.

There are methods on the MediaRecord object you can alter - Android MediaRecorder object

void     setAudioEncoder(int audio_encoder)
    Sets the audio encoder to be used for recording.
void     setAudioEncodingBitRate(int bitRate)
    Sets the audio encoding bit rate for recording.
void     setAudioSamplingRate(int samplingRate)
    Sets the audio sampling rate for recording.

Try changing those and see if any of the changes helps with the audio quality.

typo.pl
  • 8,812
  • 2
  • 28
  • 29