Issue
I have been working on a VoIP application (usually operated in speaker mode). The problem I am facing is that the behavior of audio recording is quite different for different models of smartphones.
Let me add a picture and explain it from there:
href="https://i.stack.imgur.com/enTaf.png" rel="nofollow noreferrer">
Most android smartphone has two mics. One at the top and One at the bottom. When I start capturing audio, some phones capture audio from the top mic while others from the bottom mic. Then there are some phones which are capturing audio from both mics.
The problem I am facing is the attenuation in the audio quality and voice diminishing when I have placed my phone in front of me on the table with the screen side facing upward. Some phones capture from the bottom mic, which provides good quality, while others capture from the top mic, and this causes issues.
Hopefully, you guys have understood the scenario. Now following are the things I need your help for
- How do I determine which mic is used for audio capturing? I have set the settings as follows:
- I have already tried separating different channels (L/R) and compute RMS to determine which channel is loud and map that to a specific mic. Still, unfortunately, this didn't work, as energy was the same on both media. It infers that when we select a channel in stereo, it captures data from one mic and then stores it in stereo form (L, R) in PCM_16Bit.
- I tried using CHANNEL_IN_MONO, but the mic direction (which the mic is used for audio capturing) is still not fixable or detectable.
I have tried using Whatsapp on the same devices, and it captures audio perfectly, but it doesn't happen in my case.
Thanks.
Solution
So after researching and getting some valuable answers from Stackoverflow. I finally succeeded in setting up the desired mic to capture input audio.
This question How to select physical microphone and audio recording path in Android helped me get the desired information.
I run this code:
val audioDeviceInfo = audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)
var audioInfo :AudioDeviceInfo? = null
for (dev in audioDeviceInfo) {
if(dev.address == "bottom"){
Log.d("TAGAudioInfo", dev.id.toString())
audioInfo = dev
}
}
So what does this code do?
This code gets all the input audio devices currently attached to your android phone. The returned list includes built-in and external devices, such as microphones. Now the important thing is the AudioDeviceInfo
address
attribute. This attribute tells us about the physical position of the input device.
For the mic, there are two primary addresses.
- Bottom
- Back (which is usually the mic at the top)
So what next after getting this information?
Next step is to set this mic as preferred device to capture audio. The setting of the mic is easy to do as following:
audioRecord.setPreferredDevice(audioInfo);
To cross-verify, you can use the OboeTester Application available on Google Playstore, which allows you to select any source to capture audio.
So, in this way, I resolved this issue of capturing audio from desired mic.
Also, please note that this varies from manufacturer to manufacturer of devices. Even after selecting the bottom
microphone, some devices still use both mics to capture audio. But this doesn't affect me as my primary purpose of capturing audio from the bottom microphone is resolved.
Answered By - Khubaib Ahmad
Answer Checked By - Marilyn (JavaFixing Volunteer)