如何使用android.media.AudioRecord
进行录音,而无需任何依赖智能手机制造商的花式信号处理,如自动增益控制(AGC)和/或均衡,噪音抑制,回声消除,......只需纯麦克风信号φ
MediaRecorder.AudioSource
提供了九个常量,
DEFAULT
和MIC
最初在那里,VOICE_UPLINK
,VOICE_DOWNLINK
和VOICE_CALL
,CAMCORDER
和VOICE_RECOGNITION
VOICE_COMMUNICATION
,REMOTE_SUBMIX
在API 19中添加,但第三方应用程序无法使用。但他们都没有在所有智能手机上做得干净。相反,我必须自己发现,哪个设备使用哪个MediaRecorder.AudioSource
恒定的信号处理块组合。
在API级别20中添加第10个常量(例如PURE_MIC
会很高兴。
但只要没有,我该怎么做呢?
答案 0 :(得分:6)
简短回答是“没什么”。
AudioSources对应于各种逻辑音频输入设备,具体取决于您连接到手机的附件和当前用例,而当前用例又对应于物理设备(主要内置麦克风,辅助麦克风,有线耳机麦克风)等等。用不同的调音。
OEM对每个这样的物理设备和调整组合进行调整,以满足外部要求(例如CTS,操作员要求等)和OEM本身设置的内部声学要求。此过程可能会导致各种滤波器(如AGC,噪声抑制,均衡等)进入硬件编解码器或多媒体DSP级别的音频输入路径。
虽然PURE_MIC
来源可能对某些应用程序有用,但它不是今天可用的。
在许多设备上,您可以使用amixer
写入硬件编解码器的ALSA控件来控制麦克风增益,甚至可能是过滤器链。但是,这显然是一种非常特定于平台的方法,我也怀疑你必须以root用户或音频用户身份运行才能执行此操作。
答案 1 :(得分:2)
默认情况下,某些设备会将AGC效果添加到声音输入区域。因此,您需要获取对相应AudioEffect对象的引用并强制它禁用。
首先,获取链接到AudioRecord音频会话的AutomaticGainControl对象,然后将其设置为禁用:
if (AutomaticGainControl.isAvailable()) {
AutomaticGainControl agc = AutomaticGainControl.create(
myAudioRecord.getAudioSessionId()
);
agc.setEnabled(false);
}
答案 2 :(得分:1)
注意:大多数音频源(包括DEFAULT)都会对音频信号进行处理。要录制原始音频,请选择UNPROCESSED。某些设备不支持未处理的输入。首先调用AudioManager.getProperty(“PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED”)以验证它是否可用。如果不是,请尝试使用VOICE_RECOGNITION,而不使用AGC或噪声抑制。即使不支持该属性,也可以将UNPROCESSED用作音频源,但在这种情况下无法保证信号是否未被处理。
Android文档链接https://developer.android.com/guide/topics/media/mediarecorder.html#example
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(audioManager.getProperty(AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED) !=null)
mRecorder.setAudioSource(MediaRecorder.AudioSource.UNPROCESSED);
else
mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION);
答案 3 :(得分:0)
MIC
应该很好,其余的则需要知道它们是否受支持。
我为此做了一堂课
enum class AudioSource(val audioSourceValue: Int, val minApi: Int) {
VOICE_CALL(MediaRecorder.AudioSource.VOICE_CALL, 4), DEFAULT(MediaRecorder.AudioSource.DEFAULT, 1), MIC(MediaRecorder.AudioSource.MIC, 1),
VOICE_COMMUNICATION(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 11), CAMCORDER(MediaRecorder.AudioSource.CAMCORDER, 7),
VOICE_RECOGNITION(MediaRecorder.AudioSource.VOICE_RECOGNITION, 7),
VOICE_UPLINK(MediaRecorder.AudioSource.VOICE_UPLINK, 4), VOICE_DOWNLINK(MediaRecorder.AudioSource.VOICE_DOWNLINK, 4),
@TargetApi(Build.VERSION_CODES.KITKAT)
REMOTE_SUBMIX(MediaRecorder.AudioSource.REMOTE_SUBMIX, 19),
@TargetApi(Build.VERSION_CODES.N)
UNPROCESSED(MediaRecorder.AudioSource.UNPROCESSED, 24);
fun isSupported(context: Context): Boolean =
when {
Build.VERSION.SDK_INT < minApi -> false
this != UNPROCESSED -> true
else -> {
val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && "true" == audioManager.getProperty(AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED)
}
}
companion object {
fun getAllSupportedValues(context: Context): ArrayList<AudioSource> {
val values = AudioSource.values()
val result = ArrayList<AudioSource>(values.size)
for (value in values)
if (value.isSupported(context))
result.add(value)
return result
}
}
}