mtk android 4.4 audio framework 代码分析(未完成),有需要的朋友可以参考下。
2/28/2015 3:01:24 PM
关于 audio_policy.conf 文件这个文件 mediatek/config/$project 下, 在 audiomtkpolicymanager.cpp 中解析,
解析出如下信息:
1) ATTACHED_OUTPUT_DEVICES_TAG "attached_output_devices" ,对应 类定义中的变量 mAttachedOutputDevices
2 ) #define DEFAULT_OUTPUT_DEVICE_TAG "default_output_device"
对应类定义中的 mDefaultOutputDevice
#define ATTACHED_INPUT_DEVICES_TAG "attached_input_devices"
对应类定义中的 mAvailableInputDevices
mHasA2dp = true; 根据文件解析出是否有此MODULE。
mHasUsb = true; 根据文件接触出是否有此MODULE。
mHasRemoteSubmix = true; 根据文件接触出是否有此MODULE。
3)
最重要的解析出 mHwModules,而这个变量的定义在audiomtkpolicymanager.h 中,Vector
上面关于文件解析的东西其实也属于本节的内容,不过还是单独出去了。
-》mpClientInterface = clientInterface; 就是APS
-》 AudioMTKPolicyManager::LoadCustomVolume
-》GetVolumeVer1ParamFromNV 从NVRAM里读取参数,这个暂且不表。
-》initializeVolumeCurves(); // 初始化VOLUME曲线,SETVOLUME时会用到,以后分析。
-》if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR)
上面已经分析了,解析配置文件。
-》mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
mHandle 是 audio_module_handle_t类型,实际上是 AF中成员变量DefaultKeyedVector
原型:
uint32_t AudioMTKPolicyManager::setOutputDevice(audio_io_handle_t output,
audio_devices_t device,
bool force,
int delayMs)
-》
AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); 根据传入参数取得 outputDesc
-》
if (outputDesc->isDuplicated()) { // 蓝牙,暂且不分析
muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs);
muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs);
return muteWaitMs;
}
-》
if (device != AUDIO_DEVICE_NONE) {
outputDesc->mDevice = device;
} // 设置 outputDesc route to 传入的 device. 软件层面上的。
-》
muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
-》
param.addInt(String8(AudioParameter::keyRouting), (int)device); 设置keyroute 的PARA,
-》
mpClientInterface->setParameters(output, param.toString(), delayMs); APS cmd thread 切换。
-》 // update stream volumes according to new device
applyStreamVolumes(output, device, delayMs);
分析见下面。
设备路由:
mpClientInterface->setParameters(output, param.toString(), delayMs); APS cmd thread 切换。
定义 void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
const char *keyValuePairs,
int delayMs)
{
mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
delayMs);
}
-》 AudioCommand *command = new AudioCommand();
-》 insertCommand_l(command, delayMs);
-》 AudioCommandThread::threadLoop()
-》case SET_PARAMETERS: AudioSystem::setParameters
-》 af->setParameters
-》 thread = checkPlaybackThread_l(ioHandle); 找到 相应的 thread
-》 thread->setParameters(keyValuePairs);
-》 ThreadBase::setParameters(const String8& keyValuePairs)
-》 mNewParameters.add(keyValuePairs);
Vector<String8> mNewParameters 是 ThreadBase的成员变量。
-》 PlaybackThread::threadLoop()
-》 status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
keyValuePair.string());
mOutput 是AudioStreamOut 类型:
struct AudioStreamOut {
AudioHwDevice* const audioHwDev;
audio_stream_out_t* const stream;
audio_hw_device_t* hwDev() const { return audioHwDev->hwDevice(); }
AudioStreamOut(AudioHwDevice *dev, audio_stream_out_t *out) :
audioHwDev(dev), stream(out) {}
};
-》 out->stream.common.set_parameters = out_set_parameters; HAL层
-》 status_t AudioMTKStreamOut::setParameters(const String8 &keyValuePairs)
{
AudioParameter param = AudioParameter(keyValuePairs);
String8 keyRouting = String8(AudioParameter::keyRouting);
status_t status = NO_ERROR;
int devices = 0;
ALOGD("setParameters() %s", keyValuePairs.string());
if (param.getInt(keyRouting, devices) == NO_ERROR) {
param.remove(keyRouting);
dokeyRouting(devices);
mAudioResourceManager->doSetMode();
}
if (param.size()) {
status = BAD_VALUE;
}
return status;
}
-》 AudioMTKStreamOut::dokeyRouting(uint32_t new_device)
-》 mAudioResourceManager->SelectOutputDevice(new_device);
-》 AudioResourceManager::SelectOutputDevice(uint32_t new_device)
AudioResourceManager::SelectOutputDevice 分析
pre_device = mDlOutputDevice;
-》 StopOutputDevice(); // 关掉 mDlOutputDevice,
-》 mDlOutputDevice = new_device; 设置NEW device。
-》 AudioResourceManager::StartOutputDevice()
AudioResourceManager::StartOutputDevice() 分析定义:
switch (mAudioMode) {
case AUDIO_MODE_NORMAL:
case AUDIO_MODE_RINGTONE: {
TurnonAudioDevice(mDlOutputDevice);
break;
}
case AUDIO_MODE_IN_CALL:
case AUDIO_MODE_IN_CALL_2: {
TurnonAudioDeviceIncall(mDlOutputDevice);
break;
}
case AUDIO_MODE_IN_COMMUNICATION: {
TurnonAudioDevice(mDlOutputDevice);
break;
}
}
-》 AudioResourceManager::TurnonAudioDevice(unsigned int mDlOutputDevice)
-》 mAudioAnalogInstance->AnalogOpen(AudioAnalogType::DEVICE_OUT_EARPIECER,
AudioAnalogType::DEVICE_PLATFORM_MACHINE); 打开对应的设备。
-》 AudioAnalogControl::AnalogOpen
定义:
// analog open power , need to open by mux setting
status_t AudioAnalogControl::AnalogOpen(AudioAnalogType::DEVICE_TYPE DeviceType, AudioAnalogType::DEVICE_TYPE_SETTING Type_setting)
{
ALOGD("AnalogOpen DeviceType = %s", kAudioAnalogDeviceTypeName[DeviceType]);
CheckDevicePolicy((uint32*)&DeviceType,AudioAnalogType::AUDIOANALOG_DEVICE);
mBlockAttribute[DeviceType].mEnable = true;
mAudioPlatformDevice->AnalogOpen(DeviceType); 直接操作KERNEL 接口,寄存器。
mAudioMachineDevice->AnalogOpen(DeviceType);
return NO_ERROR;
}
音量调节 AudioMTKPolicyManager::applyStreamVolumes 分析
void applyStreamVolumes(audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false); // 注意调用此传入的参数。
-》
for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
checkAndSetVolume(stream,
mStreams[stream].getVolumeIndex(device),
output,
device,
delayMs,
force);
}
-》传入的参数 StreamDescriptor mStreams[AudioSystem::NUM_STREAM_TYPES]; // stream descriptors for volume control 定义, 实际上类似于一个二维数组,STREAM是第一维, DEVICE是第二维。 上述代码实际上是取出音量的index(int).
class StreamDescriptor
{
public:
StreamDescriptor();
int getVolumeIndex(audio_devices_t device);
void dump(int fd);
int mIndexMin; // min volume index
int mIndexMax; // max volume index
KeyedVector<audio_devices_t, int> mIndexCur; // current volume index per device
bool mCanBeMuted; // true is the stream can be muted
const VolumeCurvePoint *mVolumeCurve[DEVICE_CATEGORY_CNT];
#ifdef MTK_AUDIO
float mIndexRange;
#endif
};
checkAndSetVolume 分析
AudioMTKPolicyManager::checkAndSetVolume
定义:
status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false); // 注意 后面2个参数。
-》
if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
ALOGV("checkAndSetVolume() stream %d muted count %d",
stream, mOutputs.valueFor(output)->mMuteCount[stream]);
return NO_ERROR;
} do not change actual stream volume if the stream is muted
-》
// do not change in call volume if bluetooth is connected and vice versa
if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
(stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
ALOGD("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
return INVALID_OPERATION;
}
-》
float volume = computeVolume(stream, index, output, device); // 计算音量。 后面详细分析、
-》