本文的重点则是讲述,audio从应用层到底层的初始化调用过程:不过重点是在audioTack与AudioFlinger的交互过程。应用层的几个API重要的类,AudioTrack,AudioRecoder,MediaRecoder,MediaPlayer,AudioManager等。MediaRecoder和AudioRecoder都是录音的类,但是MediaRecoder内部有压缩音频源的API,AudioRecoder只是简单的处理原始的音频,相对于录音,则播放音频的则是AudioTrack和MediaPlayer,二者的区别如下:播放声音可以用MediaPlayer和AudioTrack,两者都提供了java API供应用开发者使用。虽然都可以播放声音,但两者还是有很大的区别的。其中最大的区别是MediaPlayer可以播放多种格式的声音文件,例如MP3,AAC,WAV,OGG,MIDI等。MediaPlayer会在framework层创建对应的音频解码器。而AudioTrack只能播放已经解码的PCM流,如果是文件的话只支持wav格式的音频文件,因为wav格式的音频文件大部分都是PCM流。AudioTrack不创建解码器,所以只能播放不需要解码的wav文件。当然两者之间还是有紧密的联系,MediaPlayer在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack,AudioTrack再传递给AudioFlinger进行混音,然后才传递给硬件播放,所以是MediaPlayer包含了AudioTrack。如下一张图是从网络上看到的,非常全面,摘抄如下:应用实例:int frequency = 11025;int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; int buffersize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding); audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,frequency, channelConfiguration, audioEncoding, buffersize); byte[]buffer = new byte[buffersize]; audioRecord.startRecording();audioRecord.read(buffer, 0, bufferReadSize);audioRecord.stop();首先这里几个目的:1>分析AudioTrack和AudioRecoder,并沿着JNI一直分析到audioFlinger,Hardware等:AudioStreamIn和AudioStreamout.2>丰富Audio调用过程中的几个概念.以AudioTrack为主线,从audioTrack到HAL的过程分析.Audio系统是一个相对比较复杂的系统,也是一个典型的native的服务,这里我自己的分类为,(1)AMS,PMS,WMS等为JAVA系统级服务,AlamManagerservice等的与硬件操作相关的为插件服务,audio和Surfaceflinger,camera等为native服务。按照JAVA服务的调用流程,API->aidl->service->jni->hal->kernel.这里的Native的服务核心则是在native下,JAVA世界只是一个接口,故相当的简单,JAVA世界简单分析。这里则是讲的是音频播放操作的流程,并不包含应用层stream流的操作。int bufsize = AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT); audioplayer =new AudioTrack(AudioManager.STREAM_MUSIC,11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT, bufsize,AudioTrack.MODE_STREAM);audioplayer.play();audioplayer.write(buffer, 0 , size);//播放audioplayer.stop();int bufsize = AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT);这个执行的目的则是检测frequency-播放音频的采样率,第二个是音频通道的数量通常指的是播放时几个扬声器等,录音是几个麦克风:AudioFormat.CHANNEL_CONFIGURATION_MONO;//channelConfiguration AudioFormat.CHANNEL_CONFIGURATION_STEREO; AudioFormat.CHANNEL_CONFIGURATION_INVALID; AudioFormat.CHANNEL_CONFIGURATION_DEFAULT;第三个是音频的采样精度:AudioFormat.ENCODING_DEFAULT;//audioEncoding AudioFormat.ENCODING_INVALID; AudioFormat.ENCODING_PCM_16BIT; 16个bit相当于两个字节。AudioFormat.ENCODING_PCM_8BIT;如此将进入AudioTack.java,这里是只是标记重点的函数。 static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)这里是音道赋值。switch(channelConfig) { case AudioFormat.CHANNEL_OUT_MONO: case AudioFormat.CHANNEL_CONFIGURATION_MONO: channelCount = 1; break; case AudioFormat.CHANNEL_OUT_STEREO: case AudioFormat.CHANNEL_CONFIGURATION_STEREO: channelCount = 2; break;检测应用demo输入的sampleRateInHz是否在系统支持的RATE之内。 if ( (sampleRateInHz AudioFormat.SAMPLE_RATE_HZ_MAX) ) { loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate."); return ERROR_BAD_VALUE;}如下将进入到android_media_AudioTrack.cpp的世界,这里是JNI调用。这里或许会有个好奇,为什么JAVA世界不能判断完毕,还要进入到native世界,这里主要是与硬件有关的参数,需要进入到native世界才能拿到参数判断。这里的返回值size就是在new AudioTrack时使用的。int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thiz,jint sampleRateInHertz, jint channelCount, jint audioFormat)这里进入到AudioTrack.cpp里来判断sampleRateInHertz和音频格式是不是适合当前的硬件信息。 const status_t status = AudioTrack::getMinFrameCount(&frameCount,AUDIO_STREAM_DEFAULT,sampleRateInHertz);audioFormatToNative判断是否支持。开始进入到第二句的分析:这里只是开辟一块共享内存,基于/dev/ashmem,具体研究下ashmem的共享内存机制。与binder和log为Android创造的三大机制。audioplayer =new AudioTrack(AudioManager.STREAM_MUSIC,11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT, bufsize,AudioTrack.MODE_STREAM);这里只是一个简单的调用,不在太多废话,只是简单介绍一个数据流格式,STREAM_MUSIC和MODE_STREAMMODE_STREAM模式是针对于音乐播放等时长比较长的播放,比如播放周杰伦的千里之外,就是这种,将音频数据分段多次写入共享内存里,有延时,MODE_STATIC则是针对铃声等短音频,一次将音频数据全部写入。二者的差异则是在共享内存的开辟地点,一个在Audioflinger,一个在audiotrack。STREAM_MUSIC则是对数据定义,这里大家看到就明白了吧。啰嗦一句,这里划分主要是根据应用的策略有关,因为在audioflinger里,策略决定路由策略,路由策略决定MixerThread,再决定音频播放或者录音设备。STREAM_MUSICSTREAM_ALARMSTREAM_RINGSTREAM_VOICE_CALLSTREAM_SYSTEMnative_setupandroid_media_AudioTrack_setupswitch (memoryMode) { case MODE_STREAM:status = lpTrack->set ........ case MODE_STATIC:这里就是STATIC模式在理开辟共享内存。PS:这里仅仅是介绍流程,很多技术细节,水平有限慢慢专研。共享内存的操作细节有在做分析 // AudioTrack is using shared memory if (!lpJniStorage->allocSharedMem(buffSizeInBytes)) { goto native_init_failure; } status = lpTrack->set ........进入到audioTack.cpp的set函数status_t AudioTrack::set(........if (cbf != NULL) { mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/); // thread begins in paused state, and will not reference us until start()}这里的mAudioTrackThread主要作用如下:这个线程是用于AudioTrack(native)与AudioTrack(java)间的数据事件通知的. status_t status = createTrack_l();....createTrack_l......这里重点分析的几个函数如下:这里牵扯到main_audioserver.cpp,在init.*.rc中。以service形式启动,不过在Android6.0以前是在main_mediaserver.cpp中。这里主要干的事情很简单,1>将服务add servicemanager中,然后new audioflinger和Audiopolicyservice,其中audiopolicyservice中会创建一个新的线程MixerThread。 sp proc(ProcessState::self()); sp sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); AudioFlinger::instantiate(); AudioPolicyService::instantiate(); RadioService::instantiate(); SoundTriggerHwService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool();这里从audioTrack.cpp进到AudioFlinger.cpp中调用是基于进程间binder机制通信,C++多态的调用机制,看过Android代码的同行应该很熟悉的。virtual status_t getOutputForAttr.....->status_t status = remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply);....->status_t BnAudioPolicyService::onTransact ....->audioPolicyservice的getOutputForAttr的函数。这里只是binder机制的初步解释。IAudioPolicyService.cpp(这里主要是与policy有关,比如输出蓝牙还是耳机,音量大小等)IAudioTrack.cpp(这里主要是start,stop,play...等接口)IAudioFlinger.cpp(这里主要是setStreamVolume等)servicemanager的常见用法,binder = sm->getService(String16("media.audio_flinger"));const sp& audioFlinger = AudioSystem::get_audio_flinger();这里插入一个题外话,初始化过程:首先Audio系统根据流类型找到对应的路由策略,这里的路由策略指的是如下:enum routing_strategy{STRATEGY_MEDIA,STRATEGY_PHONE,STRATEGY_SONIFICATION,STRATEGY_DTMF,NUM_STRATGEIES}AudioPolicyService的主要目的是:输入输出设备的连接状态,系统的音频策略(strategy)的切换,音量/音频参数的设置AudioPolicyInterfaceImpl.cpp中定义了AudioPolicyService得到相关函数。初始化流程如下:根据流类型找到对应的路由策略根据该策略找到合适的device(比如扬声器,耳机)根据device选择合适的工作线程,MixerThread,蓝牙,DSP,DuplicatingThread,AT根据得到的工作线程索引号,创建一个对方的Track,然后添加到MixerThread中。status = AudioSystem::getOutputForAttr(attr, &output, mSessionId, &streamType, mClientUid, mSampleRate, mFormat, mChannelMask, mFlags, mSelectedDeviceId, mOffloadInfo);->这里进入到IAudioPolicyService.cpp的getOutputForAttr,通过binder机制,进入到AudioPolicyService.cpp的getOutputForAttr执行。-->AudioPolicyInterfaceImpl.cpp 这里定义着AudioPolicyService中很多函数实现。---> return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate,format, channelMask, flags, selectedDeviceId, offloadInfo);这里的mAudioPolicyManager定义细节如下:AudioPolicyInterface *mAudioPolicyManager;故根据继承关系可以知道,AudioPolicyInterface类定义了一个纯虚函数getOutputForAttrclass AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserver---->故最后执行到AudioPolicyManager.cpp的getOutputForAttr。继续追踪代码发现如下:----->getOutputForDevice::mpClientInterface->openOutput:_l这里的mpClientInterface是执行的AudioPolicyClient.cppsp af = AudioSystem::get_audio_flinger();af->openInput(module, input, config, device, address, source, flags);继续回到AudioFlinger里分析如下:openOutput::openOutput->findSuitableHwDev_l->loadHwModule_l->load_audio_interface: rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);: rc = audio_hw_device_open(mod, dev);到此,熟悉HAL层的朋友也应该很清楚了,这里就是Hardware层寻找合适的设备。底下就是厂商的Hardware层了。这里有个文件是audio.c和audio.h承接Hardware的细节。AudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音频策略(strategy)管理,输入输出设备管理。由此可见,电话铃声可以有7个级别的音量,而音乐则可以有15个音量级别,java的代码通过jni,最后调用 AudioPolicyManager的initStreamVolume(),把这个数组的内容传入AudioPolicyManager中,这样 AudioPolicyManager也就记住了每一个音频流的音量级别。应用程序可以调用setStreamVolumeIndex设置各个音频流的音量级别,setStreamVolumeIndex会把这个整数的音量级别转化为适合人耳的对数级别,然后通过AudioPolicyService的 AudioCommandThread,最终会将设置应用到AudioFlinger的相应的Track中。AudioCommandThread这是AudioPolicyService中的一个线程,主要用于处理音频设置相关的命令。包括:START_TONESTOP_TONESET_VOLUMESET_PARAMETERSSET_VOICE_VOLUME每种命令的参数有相应的包装:class ToneDataclass VolumeDataclass ParametersDataclass VoiceVolumeDataSTART_TONE/STOP_TONE:播放电话系统中常用的特殊音调,例如:TONE_DTMF_0,TONE_SUP_BUSY等等。SET_VOLUME:最终会调用AudioFlinger进行音量设置SET_VOICE_VOLUME:最终会调用AudioFlinger进行电话音量设置SET_PARAMETERS:通过一个KeyValuePairs形式的字符串进行参数设置。创建track并add到MixerThread中。sp track = audioFlinger->createTrack ............这里是binder机制和proxy设计思想的结果,先是调用IAudioFlinger的BnAudioFlinger,通过binder的transt到onTranst函数,进而通过继承关系最终会调用到AudioFlinger的createTrack->PlaybackThread *thread = checkPlaybackThread_l(output);->track = thread->createTrack_l .....-->track = new Track .....-->mTracks.add(track);获得共享内存的细节信息。sp iMem = track->getCblk()....play的过程audiotrack::start通过mAudioTrack ->start可以知道执行的是bpAudiotrack的start,然后根据继承的关系可以知道, class TrackHandle : public android::BnAudioTracktrackHandle = new TrackHandle(track);mAudioTrack = track;由此可以知道执行到TrackHandle的start。return mTrack->start();这里最终执行到PlaybackThread的addTrack_lmTrack的定义如下:const sp mTrack;-->status_t AudioFlinger::PlaybackThread::Track::start---> status = playbackThread->addTrack_l(this);AudioFlinger::PlaybackThread::addTrack_lstatus = AudioSystem::startOutput(mId, track->streamType(), track->sessionId());aps->startOutput(output, stream, session);AudioPolicyService::startOutputmAudioPolicyManager->startOutput(output, stream, session);status_t AudioPolicyManager::startOutput---->mActiveTracks.add(track); mWaitWorkCV.broadcast();//广播一下,新的Track产生,MixerThread开始工作mWakeLockUids.add(track->uid());recoderTrack的track状态。recordTrack->mState = TrackBase::STARTING_1;与 recordTrack->mState = TrackBase::PAUSING;因此对于play和stop,release等API的操作,最终都是通过IAudioTrack.cpp执行到TrackHandle的start,stop等接口,进而执行到track的start,stop等接。PlaybackThread与MixerThread都是在AudioFlinger里当一个PlaybackThread进入主循环后(threadLoop),音频事务就正式开启了。仔细观察的话,我们会发现这个循环中会不断地调用以“threadLoop_”开头的若干接口,比如threadLoop_mix、threadLoop_sleepTime、threadLoop_standby等等。以这样的前缀开头,是因为这些函数都是在threadLoop这个主体里被调用的,可以说代表了这个PlaybackThread所需要完成的各个操作步骤。MixerThread继承与PlaybackThread,并部分改写接口函数。MixerThread--->PlaybackThread--->ThreadBase--->Thread在Threads.cpp内有几个threadLoop_xxx方法,这些方法就分别代表不同的Audio操作:操作方法功能standbythreadLoop_standby待机mixthreadLoop_mix混音writethreadLoop_write音频输出exitthreadLoop_exit退出drainthreadLoop_drain只有offload用到,还不清楚作用sleepthreadLoop_sleepTime无音频需要处理,计算睡眠时间AudioCommandThread在AudioPolicyservice里。将音量,或者设备切换状态信息传给AudioHardWare处理。AudioTrackThread在AudioTrack.cpp里这个线程本身就在应用里,给应用汇报当前音频播放状态。AudioPolicyService:音频策略的制定者,负责音频设备切换的策略抉择、音量调节策略等AudioFlinger:音频策略的执行者,负责输入输出流设备的管理及音频流数据的处理传输这里总结下,AudioTrack的new的过程则是根据Stream_Type来决定get route_strategy,进而get strategy for Audio device,创建track 并add到MixerThread中,Static或者Stream Mode决定共享内存是在哪里开辟,然后调用Start或者stop 或者release等最后会调用到Track的start,stop,release等,进而addTrack_l ->mActiveTracks.add(track); 或者broadcast_l->mSignalPending = true;mWaitWorkCV.broadcast();分析下write的执行过程:AudioTack.java中的:writenative_write_native_bytes->android_media_AudioTrack::writeToTrack如果是stream,这是调用AudioTrack的write-->written = track->write(data + offsetInSamples, sizeInBytes, blocking);--->AudioTrack.cpp::obtainBuffer,memcpy(audioBuffer.i8, buffer, toWrite);如果是Static则是直接memcpy的方式进行。-->memcpy(track->sharedBuffer()->pointer(), data + offsetInSamples, sizeInBytes);AudioTrack端作为生产者在共享内存里写入数据后,AudioFlinger端作为消费者读取数据,最后执行MixerThread线程中的threadLoop_write函数,AudioStreamOut *output = mOutput;bytesWritten = mOutput->write((char *)mSinkBuffer + offset, mBytesRemaining);最后写入到AudioStreamOut里。简单分析下AudioRecoder的过程:根据上述AudioRecoder的案例可以知道,1>getMinBufferSize:此处函数与AudioTrack一样,计算和硬件参数检测。->android_media_AudioRecord_get_min_buff_size-->AudioRecord::getMinFrameCount....---> AudioSystem::getInputBufferSize---->根据binder机制AudioFlinger.cpp和IAudioFlinger.cpp,这里就是查询参数。最终如果return 0时,意味着参数不匹配。2>new audioRecoder。audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,frequency, channelConfiguration, audioEncoding, buffersize); -->native_setup再次进入到native的世界。--->android_media_AudioRecord_setup ---->audiorecoder.cpp :: set-----> AudioRecordThread创建并run,不过无论是Track还是Recoder都是start后才开始执行相关线程。----->openRecord_l------>AudioSystem::get_audio_flinger()------>AudioSystem::getInputForAttr这里的binder机制和proxy模式,分别进入到IAudioPolicyService和AudioPolicyInterfaceImpl的getInputForAttr,这里再强调下,AudioPolicyManager.cpp是AudioPolicyService的音量和policy的具体实现。进入到AudioPolicyInterfaceImpl的getInputForAttr分析:AudioPolicyInterface *mAudioPolicyManager;mAudioPolicyManager->getInputForAttr.........同一样的套路,进入到AudioPolicyManager执行getInputForAttr,不过这里的目的是什么呢?mOutputRoutes.addRouterouting_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);*output = getOutputForDevice(device, session, *stream, samplingRate, format, channelMask, flags, offloadInfo);上诉依然是根据应用中传入的MIC找合适的getStrategy和 getDeviceForStrategy,最后执行mpClientInterface->openOutput。AudioPolicyClientInterface *mpClientInterface;mpClientInterface = AudioPolicyManagerBase::clientInterfaceclass AudioPolicyManagerBase: public AudioPolicyInterfaceAudioPolicyInterfaceclass AudioPolicyClient : public AudioPolicyClientInterfacestatus_t AudioPolicyService::AudioPolicyClient::openInputsp af = AudioSystem::get_audio_flinger();af->openInputAudioFlinger::openInput......sp AudioFlinger::openInput_l:: AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream, flags);sp thread = new RecordThread .......------>audioFlinger->openRecord class RecordHandle : public android::BnAudioRecord这里最终则是recordHandle = new RecordHandle(recordTrack);------>mAudioRecord = record;这样以后看到如上步骤,与AudioTrack相似的步骤分析。byte[]buffer = new byte[buffersize]; audioRecord.startRecording();AudioFlinger::RecordThread::start根据binder机制可以知道,执行流程如下:RecordHandle::start->RecordTrack::start->RecordThread::start recordTrack->mState = TrackBase::STARTING_2;至于活跃Track // signal thread to start mWaitWorkCV.broadcast();广播一个recoderTrack加入,让RecordThread开始干活。audioRecord.read(buffer, 0, bufferReadSize);-->lpRecorder->read--->memcpy(buffer, audioBuffer.i8, bytesRead);audioRecord.stop();--->mAudioRecord->stop();这里的mAudioRecord根binder机制和C++的多态,执行到RecordHandle---->mRecordTrack->stop();recordTrack->mState = TrackBase::PAUSING;mWaitWorkCV.broadcast();这里的思路是:RecordHandle->RecordThread,这里的track的RecordThreadRecordTrack与AudioTrack的Track一样。方法类似,按照代码思路很容易找到。AudioTrackThread:这个线程会利用audioCallBack这个函数,从用户那里pull数据,如ToneGenator模式就是这样,不过一般模式是push的方式。与AudioRecordThreadPlaybackThread与RecordThreadAudioCommandThread mappingsOut[] = { {AUDIO_DEVICE_OUT_EARPIECE, "EARPIECE"}, {AUDIO_DEVICE_OUT_SPEAKER, "SPEAKER"}, {AUDIO_DEVICE_OUT_WIRED_HEADSET, "WIRED_HEADSET"}, {AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "WIRED_HEADPHONE"}, {AUDIO_DEVICE_OUT_BLUETOOTH_SCO, "BLUETOOTH_SCO"}, {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, "BLUETOOTH_SCO_HEADSET"}, {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, "BLUETOOTH_SCO_CARKIT"}, {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, "BLUETOOTH_A2DP"}, {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,"BLUETOOTH_A2DP_HEADPHONES"}, {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, "BLUETOOTH_A2DP_SPEAKER"}, {AUDIO_DEVICE_OUT_AUX_DIGITAL, "AUX_DIGITAL"}, {AUDIO_DEVICE_OUT_HDMI, "HDMI"}, {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET,"ANLG_DOCK_HEADSET"}, {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,"DGTL_DOCK_HEADSET"}, {AUDIO_DEVICE_OUT_USB_ACCESSORY, "USB_ACCESSORY"}, {AUDIO_DEVICE_OUT_USB_DEVICE, "USB_DEVICE"}, {AUDIO_DEVICE_OUT_TELEPHONY_TX, "TELEPHONY_TX"}, {AUDIO_DEVICE_OUT_LINE, "LINE"}, {AUDIO_DEVICE_OUT_HDMI_ARC, "HDMI_ARC"}, {AUDIO_DEVICE_OUT_SPDIF, "SPDIF"}, {AUDIO_DEVICE_OUT_FM, "FM"}, {AUDIO_DEVICE_OUT_AUX_LINE, "AUX_LINE"}, {AUDIO_DEVICE_OUT_SPEAKER_SAFE, "SPEAKER_SAFE"}, {AUDIO_DEVICE_OUT_IP, "IP"}, {AUDIO_DEVICE_OUT_BUS, "BUS"}, {AUDIO_DEVICE_NONE, "NONE"}, // must be last mappingsIn[] = { {AUDIO_DEVICE_IN_COMMUNICATION, "COMMUNICATION"}, {AUDIO_DEVICE_IN_AMBIENT, "AMBIENT"}, {AUDIO_DEVICE_IN_BUILTIN_MIC, "BUILTIN_MIC"}, {AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, "BLUETOOTH_SCO_HEADSET"}, {AUDIO_DEVICE_IN_WIRED_HEADSET, "WIRED_HEADSET"}, {AUDIO_DEVICE_IN_AUX_DIGITAL, "AUX_DIGITAL"}, {AUDIO_DEVICE_IN_VOICE_CALL, "VOICE_CALL"}, {AUDIO_DEVICE_IN_TELEPHONY_RX, "TELEPHONY_RX"}, {AUDIO_DEVICE_IN_BACK_MIC, "BACK_MIC"}, {AUDIO_DEVICE_IN_REMOTE_SUBMIX, "REMOTE_SUBMIX"}, {AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, "ANLG_DOCK_HEADSET"}, {AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, "DGTL_DOCK_HEADSET"}, {AUDIO_DEVICE_IN_USB_ACCESSORY, "USB_ACCESSORY"}, {AUDIO_DEVICE_IN_USB_DEVICE, "USB_DEVICE"}, {AUDIO_DEVICE_IN_FM_TUNER, "FM_TUNER"}, {AUDIO_DEVICE_IN_TV_TUNER, "TV_TUNER"}, {AUDIO_DEVICE_IN_LINE, "LINE"}, {AUDIO_DEVICE_IN_SPDIF, "SPDIF"}, {AUDIO_DEVICE_IN_BLUETOOTH_A2DP, "BLUETOOTH_A2DP"}, {AUDIO_DEVICE_IN_LOOPBACK, "LOOPBACK"}, {AUDIO_DEVICE_IN_IP, "IP"}, {AUDIO_DEVICE_IN_BUS, "BUS"}, {AUDIO_DEVICE_NONE, "NONE"}, // must be last};AudioPolicyservice分析如下:main_audioserver.cppAudioPolicyService::instantiate();经过分析,最终执行到AudioPolicyservice的onFirstRef这里是强指针的概念。mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this); // start audio commands threadmAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this); // start output activity command threadmOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);int rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);mAudioPolicyClient = new AudioPolicyClient(this);mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);-->AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)构造函数分析:这里拉出几个重点函数进行分析:status_t status = mpClientInterface->openOutput有刚AudioRecoder的分析,这里直接执行了AudioFlinger的openOutputAudioStreamOut *outputStream = NULL;这里从AudioPolicyService的接口调用而来。因此AudioPolicyService的实际执行者是AudioPolicyManager 。class AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserverclass AudioPolicyClient : public AudioPolicyClientInterfacestatus_t AudioPolicyService::AudioPolicyClient::openOutputstatus_t AudioPolicyService::AudioPolicyClient::openInput这里最终指向AudioFlinger的openOutput和openInputAudioPolicyService::AudioPolicyClientstatus_t status = outHwDev->openOutputStream......thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);mPlaybackThreads.add(*output, thread);这里说明AudioOut是在Main_audioserver进程里初始化,并添加,但是AudioIn则是在new AudioRecoder时,但是AudioPolicyManager这里的构造函数里也有AudioFlinger的openInput的接口调用,为啥呢?以上是设备的定义,余下时间分析AudioManager的分析。 10-29 15:24