Android静音过程分析
当接通电话时,有时候我们需要mute我们的microphone.
在系统里是如何工作的.下面简要分析一下:
通过以下结构体来完成新的audiohardware 与 legacy audiohardware的兼容
typedefstruct audio_config audio_config_t
typedefstruct audio_hw_device audio_hw_device_t;
typedefstruct audio_stream_in audio_stream_in_t;
typedefstruct audio_stream_out audio_stream_out_t;
structlegacy_audio_module {
structaudio_module module;
};
structlegacy_stream_out {
structaudio_stream_out stream;
AudioStreamOut*legacy_out;
};
structlegacy_stream_in {
structaudio_stream_in stream;
AudioStreamIn*legacy_in;
};
structlegacy_audio_device {
structaudio_hw_device device;
structAudioHardwareInterface *hwif;
};
classAudioStreamInALSA : public AudioStreamIn, public RefBase
classAudioStreamOutALSA : public AudioStreamOut, public RefBase
classAudioHardware : public AudioHardwareBase
最终由AudioHardware.cpp set_mic_mute 函数完成mute功能。
AudioHardware::setMicMute(bool state)
if (mic_volume_ctl) {
mic_volume_max = mixer_ctl_get_range_max(mic_volume_ctl);
mic_volume_min = mixer_ctl_get_range_min(mic_volume_ctl);
volume_num = mixer_ctl_get_num_values(mic_volume_ctl);
for ( i = 0; i < volume_num; i++) {
if (mMicMute)
mixer_ctl_set_value(mic_volume_ctl, i, mic_volume_min);
else
mixer_ctl_set_value(mic_volume_ctl, i, mic_volume_max);
但是有些麦克的硬件不能完成真正的静音,也就是设置到最小音量值,依然保留很小的声音。
为了实现完全的静音,可以从软件层面来实现。
status_t AudioHardware::AudioStreamInALSA::getNextBuffer(struct resampler_buffer *buffer)
{
+ bool state;
+ mHardware->getMicMute(&state);
+ if (state)
+ memset(buffer->i16, 0, buffer->frame_count*2);
}
android 2.3 静音过程分析
尤其需要注意文件PhoneUtils.java中的以下函数:
================================================
private static void setMuteInternal(Phone phone, boolean muted) {
if (DBG) log("setMuteInternal: " + muted);
Context context = phone.getContext();
boolean routeToAudioManager =
context.getResources().getBoolean(R.bool.send_mic_mute_to_AudioManager);
if (routeToAudioManager) {
AudioManager audioManager =
(AudioManager) phone.getContext().getSystemService(Context.AUDIO_SERVICE);
if (DBG) log("setMicrophoneMute: " + muted);
audioManager.setMicrophoneMute(muted);
} else {
phone.setMute(muted);
=================================
It will call different branch according to the <R.bool.send_mic_mute_to_AudioManager>value defined at android/packages/apps/phone/res/values/config.xml
By default: <bool name="send_mic_mute_to_AudioManager">false</bool>
If the value is false, it will call [ phone.setMute(muted); ];
if the value is true, it will call audioManager.setMicrophoneMute(muted);