我该怎么办录音使用android.media.AudioRecord
没有像自动增益控制(AGC)和/或均衡,噪音抑制,回声消除,......只是纯粹的麦克风信号的任何智能手机制造商依赖看中信号处理?
背景
MediaRecorder.AudioSource
提供九个常数,
-
DEFAULT
和MIC
最初在那里, -
VOICE_UPLINK
, VOICE_DOWNLINK
和VOICE_CALL
在API级别4中添加, -
CAMCORDER
和VOICE_RECOGNITION
在API 7加入 -
VOICE_COMMUNICATION
在API 11中添加, -
REMOTE_SUBMIX
在API 19添加,但不提供给第三方应用程序。
但他们没有做所有的智能手机清洁工作。 相反,我必须找出自己看来,这装置使用信号处理模块的组合为其MediaRecorder.AudioSource
不变。
会是不错的第十不变像PURE_MIC
在API级别20中添加。
但只要这是不可用的,我该怎么办呢?
简短的回答是“没有”。
所述AudioSources对应于各种逻辑音频输入装置根据已连接到电话和当前的用例,其又对应于物理设备(主内置麦克风,仲麦克风,有线耳机麦克风等)的配件不同的调音。
物理设备和调谐的每个这种组合是由OEM修整,以满足外部要求(例如CTS,运营商的要求,等等)和内部声学要求由OEM自身设置。 此过程可能导致引入各种过滤器 - 如AGC,噪声抑制,均衡,等等 - 成硬件编解码器或多媒体DSP电平的音频输入路径。
虽然PURE_MIC
源可能是用于某些应用,它不是今天的可用。
在很多设备上,你可以通过使用控制的事情,如麦克风的增益,甚至可能在过滤器链, amixer
写信给硬件编解码器的ALSA控制。 然而,这显然是一个非常特定于平台的做法,我也怀疑,你必须运行作为root或音频用户被允许这样做。
某些器件增加了AGC影响到系统默认的声音输入道。 因此,你需要获得参考相应AudioEffect对象,并迫使其关闭。
首先,获得AutomaticGainControl链接到AudioRecord音频会话对象,然后设置它禁用:
if (AutomaticGainControl.isAvailable()) {
AutomaticGainControl agc = AutomaticGainControl.create(
myAudioRecord.getAudioSessionId()
);
agc.setEnabled(false);
}
注意:大多数的音频源(包括默认)应用处理音频信号。 要录制原始音频选择不作处理。 有些设备不支持未处理的输入。 呼叫AudioManager.getProperty(“PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED”)第一次以验证它是可用的。 如果不是,请尝试使用VOICE_RECOGNITION相反,不采用AGC和噪声抑制。 您可以使用未加工作为一个音频源,即使是不支持的财产,但不保证该信号是否会在这种情况下,未加工或没有。
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);
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
}
}
}