I am using media recorder for recording call in android using VOICE_COMMUNICATION & MIC mode alternatively.
RECORD_SOURCE = MediaRecorder.AudioSource.VOICE_COMMUNICATION;
//RECORD_SOURCE = MediaRecorder.AudioSource.MIC;
iAudioRecorder = new AudioRecord(RECORD_SOURCE, NATIVE_SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, RECORD_BUF_UNIT);
I saw that MIC recorded audio data has gain much greater than VOICE_COMMUNICATION (about 2/3 times) for some devices. Also background music captured by VOICE_COMMUNICATION is not as good as MIC.
Why do audio quality (like gain, responsiveness) differs for this two recording modes?
According to the Android Developer Reference for MIC and VOICE_COMMUNICATION, some pre-processing like echo cancellation, noise suppression is applied on the audio captured using VOICE_COMMUNICATION which, in turn, causes some attenuation on the data. Moreover, on doing such pre-processing, audio signals with low amplitude becomes even more weak due to this attenuation. So we feel like background audio is sort of gone away for some devices when it is too low.
Another point was varied characteristics from device to device. From this link, it solely depends on device manufacturer and they are free to decide which pre-processing should work on which modes and how.
Related
I am using the following code in my messenger calling app :
this.audioRecord = new AudioRecord(
MediaRecorder.AudioSource.DEFAULT,
Constants.SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
Constants.BUFFER_SIZE_RECORDING);
Is this the best setting for audio in calls? I have a couple of issues with echos. I tried AudioSource.MIC and VOICE_COMMUNICATION, but they perform worse. I wonder if changing any of the other variables would improve the audio quality? Any ideas about the best variable for a calling app.Also, I don't hear any audio often on Nexus 6 or pixel 2
Audio on Android is always a tough problem because manufacturers put in different audio chips with different capabilities in all phones.
That being said VOICE_COMMUNICATION should be your best bet. It is "Microphone audio source tuned for voice communications such as VoIP. It will, for instance, take advantage of echo cancellation or automatic gain control if available."
So it should already use AcousticEchoCanceler and NoiseSuppressor to get rid of echoes and other disturbing noises. But in the end, it comes down to your use-case, if you rather want unfiltered or filtered audio.
You can also try to increase the sampling rate (Constants.SAMPLE_RATE 48000 should be best since that is the sampling rate of most modern phones) and bit depth (ENCODING_PCM_16BIT to ENCODING_PCM_FLOAT) to get a better signal. Note that supported sampling rates differ from phone to phone. To find out what your phone supports adapt the solution from audio sampling rates discussion. More information about sampling rates is covered in the Sampling Audio docs.
To the problem that you often don't hear anything, that can happen if either your gain is too low (can happen with AudioSource.MIC) or if your recorder is not ready yet (I'm making an educated guess here since I don't know your code).
I'm using EZAudio FFT to analyze audio as the iPhone "hears" it. I am listening for high-pitched sounds embedded into music (17 kHz+). When the iPhone hears the sounds with no music, it records the data perfectly and hears the pitch fine. However, when music is playing the sounds are no longer heard--or only 1 in about 8 are heard. Again, I am using EZAudio, to analyze the sound. I have an Android phone that has a similar app on it (displays an graph of Hz for incoming audio waves), but the Android phone can hear these sounds.
Why would the Android phone hear these high-pitched sounds but not the iPhone? Is it because of a flaw in EZAudio or is it due to a higher quality microphone?
The answer is most likely answer is Automatic Gain Control (AGC). This is enabled by default on the microphone, and is useful for telephony or voice recording.
At 17kHz, you're probably already at a frequency at which the microphone is not particularly sensitive, however, in the absence of audio at other frequencies, the AGC will have increase the gain of the microphone. As soon as other frequencies are present, the gain reduces again, and the 17kHz signal is in the noise.
Looking at the EZAudioFFT source code, it doesn't appear to be setting up the AVAUdioSession to use measurement-mode (which disables AGC, and the HPF on the microphone).
You can achieve this with:
NSError *pError = nil;
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeMeasurement];
I'm using AudioRecord and lame to record mic input to a mp3 sample for 12 seconds. The audio is recorder as expected but I realized the volume is too low.
Is there a way to increase the volume of the recording?
There is no gain settings in the audioRecord class to play with, so you cannot control the volume of the audio being recorded. The low volume of the audio is related to the hardware and varies from device to device. Here are a few options you can try.
1) try opening in the audio record in different modes and see whats works best .
check - http://developer.android.com/reference/android/media/MediaRecorder.AudioSource.html
2) in audio record you get the raw PCM buffers. You can write a simple code/function to shift the bits (8/16 bits per channel) left or right to double or halve the gain. (Think of it as a very crude volume control)
3) try searching the net for more complex digital gain techniques for a smoother control.
There are many implementations. (There are proprietary techniques as well)
Check:
How to adjust microphone sensitivity while recording audio in android
you can also simply increase the volume of the device:
AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
int previousVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
am.setStreamVolume(AudioManager.STREAM_MUSIC, 10, 0);
{... do your things ... }
am.setStreamVolume(AudioManager.STREAM_MUSIC, previousVolume, 0);
In my case this was an easy fix and it worked with the rest of the application.
A lot of smart phone now have more than one microphone. One for voice input and another for reducing the enviroment noise.
I am wondering how could I access the two microphone's signal independently? Or turn off one of the microphone?
Any thoughts or comments are welcomed. Thanks a lot.
I'm not familiar with the Galaxy S3 specifically, but the following is true for the majority of devices I've worked with:
There's no reliable way of selecting whether to use the primary or secondary mic for a mono recording. The MIC AudioSource usually means the primary mic when doing a mono recording, and the CAMCORDER source might mean the secondary mic. But there's no guarantee for this, because it depends e.g. on the physical placement of the mics.
Recording in mono effectively turns the other mic off, and whatever noise reduction is done uses only the signal from one mic (so there's little to no reduction of dynamic noise).
One exception to this might be if you record during a voice call where both mics already have been enabled in order to do uplink noise suppression.Another exception might be if you use the VOICE_RECOGNITION AudioSource, because some vendors apply noise suppression on the signal using one or more extra mics in this use-case.
Recording in stereo records from both mics on a 2-mic device. The left channel contains the input from one mic and the right channel contains the input from the other mic, but there's no guarantee as to which physical mic the channels correspond to (again, depends on the placement).
I'm currently starting writing a software for Android which is about to measure the reverberation time of closed rooms.
I had to choose AudioRecord instead of MediaRecorder because it gives me the chance to get the raw data.
You may know that there are many different constant to choose from for the AudioFormat (e.g.: CHANNEL_IN_MONO, CHANNEL_IN_STEREO, CHANNEL_IN_PRESSURE) and you may know that in android smartphones there are more than just one microphone embedded (usually you have 2 microphones in it, in order to have noise cancellation and stuff like that).
Here comes the question: Which constant do I have to choose to be sure that only just ONE microphone is giving me the raw data?
If you do a mono recording the device should only be recording from one microphone. I'm not sure what you mean by "raw" data. There will always be some acoustic compensation processing done (e.g. automatic gain control, equalization, etc), and this is not something that you can turn off.
One thing that also will affect the recording is which AudioSource you choose. If you select CAMCORDER on a phone with 2 or more microphones you'll typically get the back microphone with far-field tuning if you do a mono recording. If you select MIC/DEFAULT you should get the primary mic, but it may be tuned for either near-field recording or far-field recording depending on the vendor (I suspect that you'd want far-field tuning if you're trying to measure room reverberation).