您的位置:首页 > 移动开发 > Android开发

mtk android 4.4 audio framework 代码分析(未完成)

2015-07-29 23:07 645 查看
mtk android 4.4 audio framework 代码分析(未完成),有需要的朋友可以参考下。

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

APS构造函数分析:
上面关于文件解析的东西其实也属于本节的内容,不过还是单独出去了。

-》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

AudioMTKPolicyManager::setOutputDevice 分析
原型: 

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);  // 计算音量。 后面详细分析、

-》

//for VT notify tone when incoming call. it's volume will be adusted in hardware.
if((stream == AudioSystem::VOICE_CALL ||stream == AudioSystem::BLUETOOTH_SCO) && mOutputs.valueFor(output)->mRefCount[stream]!=0 && mPhoneState==AudioSystem::MODE_IN_CALL)
{
volume =1.0;
}   处理特列 MODE_IN_CALL

-》

// ALPS00554824 KH: If notifiaction is exist, FM should be mute
if ((stream == AudioSystem::FM) &&
(mOutputs.valueFor(output)->mRefCount[AudioSystem::NOTIFICATION]
|| mOutputs.valueFor(output)->mRefCount[AudioSystem::RING]
|| mOutputs.valueFor(output)->mRefCount[AudioSystem::ALARM]))
{
volume =0.0;
}

-》

if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
force)    the float value returned by computeVolume() changed
// - the force flag is set ,两者有一个条件满足则可以 调节音量。

-》

mOutputs.valueFor(output)->mCurVolume[stream] = volume;
float mCurVolume[AudioSystem::NUM_STREAM_TYPES];   // current stream volume,更新软件音量。

-》

mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);   //aps  set volume

-》

int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
float volume,
audio_io_handle_t output,
int delayMs)
{
return (int)mAudioCommandThread->volumeCommand(stream, volume,
output, delayMs);
}

-》

AudioCommandThread::volumeCommand

-》

AudioCommand *command = new AudioCommand();

-》

insertCommand_l(command, delayMs);

-》

mAudioCommands.insertAt(command, i + 1);   加入到mAudioCommands的  CMD容器中。

-》

AudioCommandThread::threadLoop
while (!mAudioCommands.isEmpty()) {
nsecs_t curTime = systemTime();
// commands are sorted by increasing time stamp: execute them from index 0 and up
if (mAudioCommands[0]->mTime <= curTime) {
// 当mAudioCommands 不为空,时间来到,

-》

CASE  SET_VOLUME: {
VolumeData *data = (VolumeData *)command->mParam;
ALOGV("AudioCommandThread() processing set volume stream %d, \
volume %f, output %d", data->mStream, data->mVolume, data->mIO);
command->mStatus = AudioSystem::setStreamVolume(data->mStream,                                                                   data->mVolume,data->mIO);   //

-》

af->setStreamVolume(stream, value, output);   下面分析

### AudioFlinger::setStreamVolume 分析 ###
status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
audio_io_handle_t output)   定义

-》

thread = checkPlaybackThread_l(output);

-》

mStreamTypes[stream].volume = value;   设置软件音量
stream_type_t  mStreamTypes[AUDIO_STREAM_CNT + 1];  AF中音量表示方法。

-》

thread->setStreamVolume(stream, value);   后面分析

-》

if(stream == AUDIO_STREAM_FM)
{
MTK_ALOG_D("setStreamVolume FM  value = %f",value);
#if defined(MT5192_FM) || defined(MT5193_FM)
int FmVolume = (AudioSystem::logToLinear(value));
char Volume[30];
sprintf(Volume,"SetFmVolume=%d",FmVolume);
String8 Key = String8(Volume);
#else
int FmVolume = (AudioSystem::logToLinear(value)>>4);
char Volume[30];
sprintf(Volume,"SetFmVolume=%d",FmVolume);
String8 Key = String8(Volume);
#endif
audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
dev->set_parameters (dev,Key);
}   如果是stream 是FM, 则直接dev->set_parameters (dev,Key); 设置硬件VOLUME.

### PlaybackThread::setStreamVolume 分析 ###
struct  stream_type_t {
stream_type_t()
:   volume(1.0f),
mute(false)
{
}
float       volume;
bool        mute;
};  // AF中  和  PLAYBACKTHREAD 中都有个这样的。
定义 void AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
{
Mutex::Autolock _l(mLock);
mStreamTypes[stream].volume = value;
}

插入耳机路由切换过程 WiredAccessoryManager ###
构造函数中 
mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
 

-》 

mObserver = new WiredAccessoryObserver(); 

-》 

init 中 public String getSwitchStatePath() { 

return String.format(“/sys/class/switch/%s/state”, mDevName); 



-》 

mAudioManager.setWiredDeviceConnectionState(device, state, headsetName); 

-》 

AudioService中 public void setWiredDeviceConnectionState(int device, int state, String name) { 

synchronized (mConnectedDevices) { 

int delay = checkSendBecomingNoisyIntent(device, state); 

queueMsgUnderWakeLock(mAudioHandler, 

MSG_SET_WIRED_DEVICE_CONNECTION_STATE, 

device, 

state, 

name, 

delay); 





-》 

checkSendBecomingNoisyIntent 中 

sendMsg(mAudioHandler , MSG_BROADCAST_AUDIO_BECOMING_NOISY, 

SENDMSG_REPLACE, 

0, 

0, 

null, 

0); 

delay = 1000; 

Senmsg在handler中处理

sendBroadcastToAll(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
这个广播哪些地方有处理,举例子:MUSIC应用中

public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
MusicLogUtils.d("MediaButtonIntentReceiver", "intentAction " + intentAction);
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intentAction)) {

-》 

i.setAction(MediaPlaybackService.SERVICECMD); 

i.putExtra(MediaPlaybackService.CMDNAME, MediaPlaybackService.CMDPAUSE); 

context.startService(i); 

-》 

在 mediaplayerservice 中处理 

else if (CMDPAUSE.equals(cmd) || PAUSE_ACTION.equals(action) 

|| AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)) { 

pause(); 

mPausedByTransientLossOfFocus = false; 



-》 audioservice 中

case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
onSetWiredDeviceConnectionState(msg.arg1, msg.arg2, (String)msg.obj);

-》 

private void onSetWiredDeviceConnectionState(int device, int state, String name) 



synchronized (mConnectedDevices) { 

Log.d(TAG,”onSetWiredDeviceConnectionState:” + “device:” + device + “,state:” + state); 

if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||(device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) { // 耳机 

/// M: Change for sound output from device
when a2dp conneted @ { 

//setBluetoothA2dpOnInt(true); AudioSystem.setForceUse(AudioSystem.FOR_MEDIA,AudioSystem.FORCE_NONE); 

///@} 



boolean isUsb = ((device & AudioSystem.DEVICE_OUT_ALL_USB) != 0); 

handleDeviceConnection((state == 1), device, (isUsb ? name : “”)); 

if (state != 0) { 

if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) || 

(device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE)) { 

setBluetoothA2dpOnInt(false); 



if ((device & mSafeMediaVolumeDevices) != 0) { 

sendMsg(mAudioHandler, 

MSG_CHECK_MUSIC_ACTIVE, 

SENDMSG_REPLACE, 

0, 

0, 

null, 

MUSIC_ACTIVE_POLL_PERIOD_MS); 





if (!isUsb) { 

sendDeviceConnectionIntent(device, state, name); 





}

AudioSystem.setForceUse 分析 handleDeviceConnection(audioservice) 分析
boolean isUsb = ((device & AudioSystem.DEVICE_OUT_ALL_USB) != 0); 

handleDeviceConnection((state == 1), device, (isUsb ? name : “”)); 

下面是定义:

private boolean handleDeviceConnection(boolean connected, int device, String params) {
synchronized (mConnectedDevices) {
boolean isConnected = (mConnectedDevices.containsKey(device) &&
(params.isEmpty() || mConnectedDevices.get(device).equals(params)));
Log.d(TAG,"handleDeviceConnection:isConnected" + isConnected);

if (isConnected && !connected) { 、、 拔出
AudioSystem.setDeviceConnectionState(device,  设置状态
AudioSystem.DEVICE_STATE_UNAVAILABLE,
mConnectedDevices.get(device));
Log.d(TAG,"handleDeviceConnection remove:" + "connected:" + connected + ",device:" + device);
mConnectedDevices.remove(device);  移除设备。
return true;
} else if (!isConnected && connected) {
AudioSystem.setDeviceConnectionState(device,
AudioSystem.DEVICE_STATE_AVAILABLE,
params);
Log.d(TAG,"handleDeviceConnection connect:" + "connected:" + connected + ",device:" + device);
mConnectedDevices.put(new Integer(device), params);
return true;
}
}
return false;
}

-》

AudioSystem::setDeviceConnectionState

-》

aps->setDeviceConnectionState(

-》

AudioMTKPolicyManager::setDeviceConnectionState(audio_devices_t device,
AudioSystem::device_connection_state state,const char *device_address)

-》

case AudioSystem::DEVICE_STATE_AVAILABLE:
if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
return INVALID_OPERATION;
}
ALOGD("setDeviceConnectionState() checkOutputsForDevice() returned %d outputs",
outputs.size());
// register new device as available
mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device);     输出设备。

checkOutputForAllStrategies();  更新strategy
if ((state == AudioSystem::DEVICE_STATE_UNAVAILABLE) ||
(mOutputs.valueFor(outputs[i])->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
closeOutput(outputs[i]);   关掉 output
}
updateDevicesAndOutputs();
for (size_t i = 0; i < mOutputs.size(); i++) {
// do not force device change on duplicated output because if device is 0, it will
// also force a device 0 for the two outputs it is duplicated to which may override
// a valid device selection on those outputs.
setOutputDevice(mOutputs.keyAt(i),
getNewDevice(mOutputs.keyAt(i), true /*fromCache*/),
!mOutputs.valueAt(i)->isDuplicated(),
0);
}

### AudioMTKPolicyManager::checkOutputForAllStrategies() 分析 ###

-》

调用  AudioMTKPolicyManager::checkOutputForStrategy(routing_strategy strategy)

-》

audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);

-》

if (desc->strategyRefCount(strategy) != 0) {  //
#ifdef MTK_AUDIO    //ALPS00446176 .ex: Speaker->Speaker,Don't move track and mute. Only change to dstOutputs[0]
if(dstOutputs[0]!=srcOutputs[i])  如果现在的dstOutputs不在 srcOutputs中
{
setStrategyMute(strategy, true, srcOutputs[i]); // 立即MUTE
setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);  // 2秒后unmute  newDevice
}
#else
setStrategyMute(strategy, true, srcOutputs[i]);
setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);
#endif

}

-》

AudioMTKPolicyManager::setStrategyMute

-》

setStreamMute(stream, on, output, delayMs, device);

-》

AudioMTKPolicyManager::setStreamMute(int stream,
bool on,
audio_io_handle_t output,
int delayMs,
audio_devices_t device)

-》

if (on) { //  mute on
if (outputDesc->mMuteCount[stream] == 0) {
if (streamDesc.mCanBeMuted &&
((stream != AudioSystem::ENFORCED_AUDIBLE) ||
(mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) {
checkAndSetVolume(stream, 0, output, device, delayMs);
}
}
// increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
outputDesc->mMuteCount[stream]++;
}
checkAndSetVolume // 上面已经分析过了,最后会设置音量到 af对应的threads
接上面函数继续分析

-》

// Move tracks associated to this strategy from previous output to new output
for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
if (getStrategy((AudioSystem::stream_type)i) == strategy) {
//FIXME see fixme on name change
mpClientInterface->setStreamOutput((AudioSystem::stream_type)i,
dstOutputs[0] /* ignored */);
}
}

-》

status_t AudioPolicyCompatClient::setStreamOutput(AudioSystem::stream_type stream,
audio_io_handle_t output)
{
return mServiceOps->set_stream_output(mService, (audio_stream_type_t)stream,
output);
}

-》

aps: set_stream_output

-》

af->setStreamOutput

-》

status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
{
Mutex::Autolock _l(mLock);
ALOGV("setStreamOutput() stream %d to output %d", stream, output);

for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
thread->invalidateTracks(stream);
}

return NO_ERROR;
}

-》

PlaybackThread::cacheParameters_l()

-》

PlaybackThread:  t->mCblk->cv.signal(); 发信号, 哪里在等还没找到。

uint32_t mRefCount[AudioSystem::NUM_STREAM_TYPES]; // number of streams of each type using this output

DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mPreviousOutputs;

Audioservice中重要变量:

private final HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>();

AudioTrack 跟踪
AudioTrack.java
blic AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes, int mode, int sessionId)

-》 

int initResult = native_setup(new WeakReference(this), 

mStreamType, mSampleRate, mChannels, mAudioFormat, 

mNativeBufferSizeInBytes, mDataLoadMode, session);

-》

android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jint streamType, jint sampleRateInHertz, jint javaChannelMask,
jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession)
sp<AudioTrack> lpTrack = new AudioTrack();

-》

## AudioFlinger::openOutput  分析 ##
DefaultKeyedVector< audio_io_handle_t, sp<PlaybackThread> >  mPlaybackThreads;
在 AudioFlinger::openOutput  中 返回的就是这个audio_io_handle_t  KEY值。

AudioFlinger::openOutput

->

outHwDev = findSuitableHwDev_l(module, *pDevices); // 找到  AudioHwDevice, 对应HAL 下的一个设备。

-> 
status =
hwDevHal->open_output_stream(hwDevHal, 

id, 

*pDevices, 

(audio_output_flags_t)flags, 

&config, 

&outStream); 

outStream 是在HAL层分配的,然后返回到AF中。

-》

AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);  // 用上述2个NEW一个 AudioStreamOut。

->

if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) ||
(config.format != AUDIO_FORMAT_PCM_16_BIT) ||
(config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {
thread = new DirectOutputThread(this, output, id, *pDevices);
ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
} else {
thread = new MixerThread(this, output, id, *pDevices);
ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
附录LOG:(开机过程中)
Line 2397: 01-01 03:59:20.971207   211   211 D AudioFlinger: openOutput(), module 1 Device 2, SamplingRate 44100, Format 0x000003, Channels 3, flags 2
Line 2398: 01-01 03:59:20.971246   211   211 D AudioFlinger: openOutput(), offloadInfo 0x0 version 0xffffffff
Line 2399: 01-01 03:59:20.971291   211   211 D AudioALSAStreamManager: +openOutputStream()
Line 2888: 01-01 03:59:21.028671   211   211 D AudioALSAStreamManager: -openOutputStream(), out = 0xb7ba8250, status = 0x0, mStreamOutVector.size() = 1
Line 2889: 01-01 03:59:21.028791   211   211 D AudioFlinger: openOutput() openOutputStream returned output 0xb7ba81e0, SamplingRate 44100, Format 0x000003, Channels 3, status 0, flags 2
Line 2889: 01-01 03:59:21.028791   211   211 D AudioFlinger: openOutput() openOutputStream returned output 0xb7ba81e0, SamplingRate 44100, Format 0x000003, Channels 3, status 0, flags 2
Line 2905: 01-01 03:59:21.048650   211   211 D AudioFlinger: openOutput() created mixer output: ID 2 thread 0xb4b26008
(在 AudioFlinger 构造函数中初始化了 mNextUniqueId(1) )

-》

AudioTrack::AudioTrack(
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
int frameCount,
audio_output_flags_t flags,
callback_t cbf,
void* user,
int notificationFrames,
int sessionId,
transfer_type transferType,
const audio_offload_info_t *offloadInfo,
int uid)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
mPausedPosition(0)
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
offloadInfo, uid);
}

}
mPlaybackThreads.add(id, thread);

-》

audio_io_handle_t output = AudioSystem::getOutput(
streamType,
sampleRate, format, channelMask,
flags,
offloadInfo);
if (cbf != NULL) {
mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/);
}

// create the IAudioTrack
status_t status = createTrack_l(streamType,
sampleRate,
format,
frameCount,
flags,
sharedBuffer,
output,
0 /*epoch*/);

-》

sp<IAudioTrack> track = audioFlinger->createTrack(streamType,
sampleRate,
// AudioFlinger only sees 16-bit PCM
format == AUDIO_FORMAT_PCM_8_BIT ?
AUDIO_FORMAT_PCM_16_BIT : format,
mChannelMask,
frameCount,
&trackFlags,
sharedBuffer,
output,
tid,
&mSessionId,
mName,
mClientUid,
&status);

-》

track = thread->createTrack_l(client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus);

-》

// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
const sp<AudioFlinger::Client>& client,
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
int uid,
status_t *status)
{
sp<Track> track;
status_t lStatus;

bool isTimed = (*flags & IAudioFlinger::TRACK_TIMED) != 0;

// client expresses a preference for FAST, but we get the final say
if (*flags & IAudioFlinger::TRACK_FAST) {
if (
// not timed
(!isTimed) &&
// either of these use cases:
(
// use case 1: shared buffer with any frame count
(
(sharedBuffer != 0)
) ||
// use case 2: callback handler and frame count is default or at least as large as HAL
(
(tid != -1) &&
((frameCount == 0) ||
(frameCount >= mFrameCount))
)
) &&
// PCM data
audio_is_linear_pcm(format) &&
// mono or stereo
( (channelMask == AUDIO_CHANNEL_OUT_MONO) ||
(channelMask == AUDIO_CHANNEL_OUT_STEREO) ) &&
#ifndef FAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
// hardware sample rate
(sampleRate == mSampleRate) &&
#endif
// normal mixer has an associated fast mixer
hasFastMixer() &&
// there are sufficient fast track slots available
(mFastTrackAvailMask != 0)
// FIXME test that MixerThread for this fast track has a capable output HAL
// FIXME add a permission test also?
) {
// if frameCount not specified, then it defaults to fast mixer (HAL) frame count
if (frameCount == 0) {
frameCount = mFrameCount * kFastTrackMultiplier;
}
ALOGV("AUDIO_OUTPUT_FLAG_FAST accepted: frameCount=%d mFrameCount=%d",
frameCount, mFrameCount);
} else {
ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: isTimed=%d sharedBuffer=%p frameCount=%d "
"mFrameCount=%d format=%d isLinear=%d channelMask=%#x sampleRate=%u mSampleRate=%u "
"hasFastMixer=%d tid=%d fastTrackAvailMask=%#x",
isTimed, sharedBuffer.get(), frameCount, mFrameCount, format,
audio_is_linear_pcm(format),
channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask);
*flags &= ~IAudioFlinger::TRACK_FAST;
// For compatibility with AudioTrack calculation, buffer depth is forced
// to be at least 2 x the normal mixer frame count and cover audio hardware latency.
// This is probably too conservative, but legacy application code may depend on it.
// If you change this calculation, also review the start threshold which is related.
uint32_t latencyMs = mOutput->stream->get_latency(mOutput->stream);
uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
if (minBufCount < 2) {
minBufCount = 2;
}

#ifdef MTK_AUDIO
size_t minFrameCount = (mFrameCount*sampleRate*minBufCount)/mSampleRate;
#else
size_t minFrameCount = mNormalFrameCount * minBufCount;
#endif
if (frameCount < minFrameCount) {
frameCount = minFrameCount;
}
}
}

if (mType == DIRECT) {
if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
ALOGE("createTrack_l() Bad parameter: sampleRate %u format %d, channelMask 0x%08x "
"for output %p with format %d",
sampleRate, format, channelMask, mOutput, mFormat);
lStatus = BAD_VALUE;
goto Exit;
}
}
} else if (mType == OFFLOAD) {
if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
ALOGE("createTrack_l() Bad parameter: sampleRate %d format %d, channelMask 0x%08x \""
"for output %p with format %d",
sampleRate, format, channelMask, mOutput, mFormat);
lStatus = BAD_VALUE;
goto Exit;
}
} else {
if ((format & AUDIO_FORMAT_MAIN_MASK) != AUDIO_FORMAT_PCM) {
ALOGE("createTrack_l() Bad parameter: format %d \""
"for output %p with format %d",
format, mOutput, mFormat);
lStatus = BAD_VALUE;
goto Exit;
}
// Resampler implementation limits input sampling rate to 2 x output sampling rate.
if (sampleRate > mSampleRate*2) {
ALOGE("Sample rate out of range: %u mSampleRate %u", sampleRate, mSampleRate);
#ifndef MTK_AUDIO
lStatus = BAD_VALUE;
goto Exit;
#endif
}
}

lStatus = initCheck();
if (lStatus != NO_ERROR) {
ALOGE("Audio driver not initialized.");
goto  Exit;
}

{ // scope for mLock
Mutex::Autolock _l(mLock);

// all tracks in same audio session must share the same routing strategy otherwise
// conflicts will happen when tracks are moved from one output to another by audio policy
// manager
uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> t = mTracks[i];
if (t != 0 && !t->isOutputTrack()) {
uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
if (sessionId == t->sessionId() && strategy != actual) {
ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
strategy, actual);
lStatus = BAD_VALUE;
goto Exit;
}
}
}

if (!isTimed) {
track = new Track(this, client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, sessionId, uid, *flags);
} else {
track = TimedTrack::create(this, client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, sessionId, uid);
}

if (track == 0 || track->getCblk() == NULL || track->name() < 0) {
lStatus = NO_MEMORY;
// track must be cleared from the caller as the caller has the AF lock
goto Exit;
}

mTracks.add(track);
ALOGD("%s, mTracks.add(), track 0x%x, this 0x%x", __FUNCTION__, track.get(), this);

sp<EffectChain> chain = getEffectChain_l(sessionId);
if (chain != 0) {
ALOGV("createTrack_l() setting main buffer %p", chain->inBuffer());
track->setMainBuffer(chain->inBuffer());
chain->setStrategy(AudioSystem::getStrategyForStream(track->streamType()));
chain->incTrackCnt();
}

if ((*flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
pid_t callingPid = IPCThreadState::self()->getCallingPid();
// we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
// so ask activity manager to do this on our behalf
sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp);
}
}

lStatus = NO_ERROR;

Exit:
if (status) {
*status = lStatus;
}
return track;
}

-》 

uint32_t actual = AudioSystem::getStrategyForStream(t->streamType()); 

track = new Track(this, client, streamType, sampleRate, format, 

channelMask, frameCount, sharedBuffer, sessionId, uid, *flags); 

-》 

AudioFlinger::PlaybackThread::Track::Track 

-》 

AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, 

size_t frameSize, bool clientInServer = false) 

: ServerProxy(cblk, buffers, frameCount, frameSize, true /isOut/, clientInServer) { } 

-》

ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
size_t frameSize, bool isOut, bool clientInServer)
: Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer),
mAvailToClient(0), mFlush(0)
{
}

然后根据这个 streamout 和ID, NEW threads. 然后ADD 到 AF中的 mPlaybackThreads。 

-》hwDevHal->set_mode(hwDevHal, mMode); // 大概是 设置MODE, NORMAL , CALL MODE? 条件是 (mPrimaryHardwareDev == NULL) ,只有第一次AudioFlinger::openOutput 时会设置模式。

HAL 层open_output_stream
Audio_hw_hal.cpp 中关于 

legacy_adev_open 中将 

ladev->device.open_output_stream = adev_open_output_stream; 

-》 adev_open_output_stream

-》 

static int adev_open_output_stream(struct
audio_hw_device *dev, 

audio_io_handle_t handle, 

audio_devices_t devices, 

audio_output_flags_t flags, 

struct audio_config *config, 

struct audio_stream_out **stream_out) 



struct legacy_audio_device *ladev = to_ladev(dev); 
status_t
status; 

struct legacy_stream_out *out; 

int ret;

out = (struct legacy_stream_out *)calloc(1, sizeof(*out));  分配内存,然后由下面设备填充。
if (!out)
return -ENOMEM;
// 打开设备,填充
out->legacy_out = ladev->hwif->openOutputStreamWithFlag(devices, (int *) &config->format,
&config->channel_mask,
&config->sample_rate, &status, flags);
if (!out->legacy_out) {
ret = status;
goto err_open;
}

out->stream.common.get_sample_rate = out_get_sample_rate;
out->stream.common.set_sample_rate = out_set_sample_rate;
out->stream.common.get_buffer_size = out_get_buffer_size;
out->stream.common.get_channels = out_get_channels;
out->stream.common.get_format = out_get_format;
out->stream.common.set_format = out_set_format;
out->stream.common.standby = out_standby;
out->stream.common.dump = out_dump;
out->stream.common.set_parameters = out_set_parameters;
out->stream.common.get_parameters = out_get_parameters;
out->stream.common.add_audio_effect = out_add_audio_effect;
out->stream.common.remove_audio_effect = out_remove_audio_effect;
out->stream.get_latency = out_get_latency;
out->stream.set_volume = out_set_volume;
out->stream.write = out_write;
out->stream.get_render_position = out_get_render_position;
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;

out->stream.set_callback = out_set_callback;
out->stream.get_presentation_position = out_get_presentation_position;

*stream_out = &out->stream;
return 0;

err_open:
free(out);
*stream_out = NULL;
return ret;
}

-》AudioHardwareALSA::openOutputStream

-》

android_audio_legacy::AudioStreamOut *AudioALSAHardware::openOutputStream(
uint32_t devices,
int *format,
uint32_t *channels,
uint32_t *sampleRate,
status_t *status)
{
return mStreamManager->openOutputStream(devices, format, channels, sampleRate, status);
}

/*============================================================================== 

* Implementations 
============================================================================/

-》 

android_audio_legacy::AudioStreamOut *AudioALSAStreamManager::openOutputStream( 

uint32_t devices, 

int *format, 

uint32_t *channels, 

uint32_t *sampleRate, 
status_t
*status) 



ALOGD(“+%s()”, FUNCTION); 

AudioAutoTimeoutLock streamVectorAutoTimeoutLock(mStreamVectorLock); 

AudioAutoTimeoutLock _l(mLock);

if (format == NULL || channels == NULL || sampleRate == NULL || status == NULL)
{
ALOGE("%s(), NULL pointer!! format = %p, channels = %p, sampleRate = %p, status = %p",
__FUNCTION__, format, channels, sampleRate, status);
if (status != NULL) { *status = INVALID_OPERATION; }
return NULL;
}

// stream out flags
const uint32_t flags = (uint32_t)(*status);

// create stream out
AudioALSAStreamOut *pAudioALSAStreamOut = new AudioALSAStreamOut();
pAudioALSAStreamOut->set(devices, format, channels, sampleRate, status, flags);
if (*status != NO_ERROR)
{
ALOGE("-%s(), set fail, return NULL", __FUNCTION__);
delete pAudioALSAStreamOut;
pAudioALSAStreamOut = NULL;
return NULL;
}

// save stream out object in vector
pAudioALSAStreamOut->setIdentity(mStreamOutIndex);
mStreamOutVector.add(mStreamOutIndex, pAudioALSAStreamOut); // 加入到streammanager 容器中。
mStreamOutIndex++;

// setup Filter for ACF/HCF/AudEnh/VibSPK // TODO Check return status of pAudioALSAStreamOut->set
AudioMTKFilterManager *pAudioFilterManagerHandler = new AudioMTKFilterManager(*sampleRate, android_audio_legacy::AudioSystem::popCount(*channels), *format, pAudioALSAStreamOut->bufferSize());
mFilterManagerVector.add(mFilterManagerNumber, pAudioFilterManagerHandler);
mFilterManagerNumber++;

ALOGD("-%s(), out = %p, status = 0x%x, mStreamOutVector.size() = %d",
__FUNCTION__, pAudioALSAStreamOut, *status, mStreamOutVector.size());

return pAudioALSAStreamOut;
}

-》audioAStreamManager::openOutputStream 

-》audioALSAStreamOut::open 

-》audioALSAStreamOut::open() 

-》playbackHandler = mStreamManager->createPlaybackHandler(&mStreamAttributeSource); 

-> // open codec
driver 

mHardwareResourceManager->startOutputDevice(mStreamAttributeSource->output_devices, mStreamAttributeTarget.sample_rate);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息