Chinaunix首页 | 论坛 | 博客
  • 博客访问: 207520
  • 博文数量: 37
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 375
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-23 21:00
个人简介

潜心静气。。慢慢出成果

文章分类

全部博文(37)

文章存档

2018年(5)

2017年(6)

2016年(23)

2015年(3)

我的朋友

分类: Android平台

2018-04-12 16:26:43

本文的重点则是讲述,audio从应用层到底层的初始化调用过程:不过重点是在audioTackAudioFlinger的交互过程。

应用层的几个API重要的类,AudioTrackAudioRecoderMediaRecoder,MediaPlayer,

AudioManager等。

MediaRecoderAudioRecoder都是录音的类,但是MediaRecoder内部有压缩音频源的APIAudioRecoder只是简单的处理原始的音频,相对于录音,则播放音频的则是AudioTrackMediaPlayer,二者的区别如下:

播放声音可以用MediaPlayerAudioTrack,两者都提供了java API供应用开发者使用。虽然都可以播放声音,但两者还是有很大的区别的。其中最大的区别是MediaPlayer可以播放多种格式的声音文件,例如MP3AACWAVOGGMIDI等。MediaPlayer会在framework层创建对应的音频解码器。而AudioTrack只能播放已经解码的PCM流,如果是文件的话只支持wav格式的音频文件,因为wav格式的音频文件大部分都是PCM流。AudioTrack不创建解码器,所以只能播放不需要解码的wav文件。当然两者之间还是有紧密的联系,MediaPlayerframework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrackAudioTrack再传递给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>分析AudioTrackAudioRecoder,并沿着JNI一直分析到audioFlingerHardware:AudioStreamInAudioStreamout.

2>丰富Audio调用过程中的几个概念.

AudioTrack为主线,从audioTrackHAL的过程分析.Audio系统是一个相对比较复杂的系统,也是一个典型的native的服务,这里我自己的分类为,(1)AMSPMSWMS等为JAVA系统级服务,AlamManagerservice等的与硬件操作相关的为插件服务,audioSurfaceflingercamera等为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;  16bit相当于两个字节。

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_MIN) || (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的共享内存机制。与binderlogAndroid创造的三大机制。

audioplayer =new AudioTrack(AudioManager.STREAM_MUSIC,11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT, bufsize,AudioTrack.MODE_STREAM);

这里只是一个简单的调用,不在太多废话,只是简单介绍一个数据流格式,STREAM_MUSICMODE_STREAM

MODE_STREAM模式是针对于音乐播放等时长比较长的播放,比如播放周杰伦的千里之外,就是这种,将音频数据分段多次写入共享内存里,有延时,MODE_STATIC则是针对铃声等短音频,一次将音频数据全部写入。二者的差异则是在共享内存的开辟地点,一个在Audioflinger,一个在audiotrack

STREAM_MUSIC则是对数据定义,这里大家看到就明白了吧。啰嗦一句,这里划分主要是根据应用的策略有关,因为在audioflinger里,策略决定路由策略,路由策略决定MixerThread,再决定音频播放或者录音设备。

STREAM_MUSIC

STREAM_ALARM

STREAM_RING

STREAM_VOICE_CALL

STREAM_SYSTEM

native_setup

android_media_AudioTrack_setup

switch (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类定义了一个纯虚函数getOutputForAttr

class AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserver

---->故最后执行到AudioPolicyManager.cpp的getOutputForAttr。

继续追踪代码发现如下:

----->getOutputForDevice

::mpClientInterface->openOutput:_l

这里的mpClientInterface是执行的AudioPolicyClient.cpp

sp 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_TONE

STOP_TONE

SET_VOLUME

SET_PARAMETERS

SET_VOICE_VOLUME

每种命令的参数有相应的包装:

class ToneData

class VolumeData

class ParametersData

class VoiceVolumeData

START_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::BnAudioTrack

trackHandle = new TrackHandle(track);

mAudioTrack = track;

由此可以知道执行到TrackHandle的start。

return mTrack->start();

这里最终执行到PlaybackThread的addTrack_l

mTrack的定义如下:

const sp mTrack;

-->status_t AudioFlinger::PlaybackThread::Track::start

---> status = playbackThread->addTrack_l(this);

AudioFlinger::PlaybackThread::addTrack_l

status = AudioSystem::startOutput(mId, track->streamType(),

                                              track->sessionId());

aps->startOutput(output, stream, session);

AudioPolicyService::startOutput

mAudioPolicyManager->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;

因此对于playstopreleaseAPI的操作,最终都是通过IAudioTrack.cpp执行到TrackHandle

start,stop等接口,进而执行到track的start,stop等接。

PlaybackThread与MixerThread都是在AudioFlinger里

当一个PlaybackThread进入主循环后(threadLoop),音频事务就正式开启了。仔细观察的话,我们会发现这个循环中会不断地调用以“threadLoop_”开头的若干接口,比如threadLoop_mixthreadLoop_sleepTimethreadLoop_standby等等。以这样的前缀开头,是因为这些函数都是在threadLoop这个主体里被调用的,可以说代表了这个PlaybackThread所需要完成的各个操作步骤。

MixerThread

继承与PlaybackThread,并部分改写接口函数。

MixerThread--->PlaybackThread--->ThreadBase--->Thread

Threads.cpp内有几个threadLoop_xxx方法,这些方法就分别代表不同的Audio操作:

操作

方法

功能

standby

threadLoop_standby

待机

mix

threadLoop_mix

混音

write

threadLoop_write

音频输出

exit

threadLoop_exit

退出

drain

threadLoop_drain

只有offload用到,还不清楚作用

sleep

threadLoop_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中的:write

native_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模式,分别进入到IAudioPolicyServiceAudioPolicyInterfaceImplgetInputForAttr,这里再强调下,AudioPolicyManager.cppAudioPolicyService的音量和policy的具体实现。

进入到AudioPolicyInterfaceImplgetInputForAttr分析:

AudioPolicyInterface *mAudioPolicyManager;

mAudioPolicyManager->getInputForAttr.........

同一样的套路,进入到AudioPolicyManager执行getInputForAttr,不过这里的目的是什么呢?

mOutputRoutes.addRoute

routing_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找合适的getStrategygetDeviceForStrategy

最后执行mpClientInterface->openOutput

AudioPolicyClientInterface *mpClientInterface;

mpClientInterface = AudioPolicyManagerBase::clientInterface

class AudioPolicyManagerBase: public AudioPolicyInterface

AudioPolicyInterface

class AudioPolicyClient : public AudioPolicyClientInterface

status_t AudioPolicyService::AudioPolicyClient::openInput

sp af = AudioSystem::get_audio_flinger();

af->openInput


AudioFlinger::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();

这里的mAudioRecordbinder机制和C++的多态,执行到RecordHandle

---->mRecordTrack->stop();

recordTrack->mState = TrackBase::PAUSING;

mWaitWorkCV.broadcast();

这里的思路是:RecordHandle->RecordThread,这里的trackRecordThread

RecordTrackAudioTrackTrack一样。

方法类似,按照代码思路很容易找到。

AudioTrackThread:

这个线程会利用audioCallBack这个函数,从用户那里pull数据,如ToneGenator模式就是这样,不过一般模式是push的方式。

AudioRecordThread

PlaybackThread与RecordThread

AudioCommandThread

  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.cpp

AudioPolicyService::instantiate();

经过分析,最终执行到AudioPolicyservice的onFirstRef

这里是强指针的概念。

mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);

        // start audio commands thread

mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);

        // start output activity command thread

mOutputCommandThread = 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的openOutput

AudioStreamOut *outputStream = NULL;

这里从AudioPolicyService的接口调用而来。因此AudioPolicyService的实际执行者是AudioPolicyManager 。

class AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserver

class AudioPolicyClient : public AudioPolicyClientInterface

status_t AudioPolicyService::AudioPolicyClient::openOutput

status_t AudioPolicyService::AudioPolicyClient::openInput

这里最终指向AudioFlinger的openOutput和openInput

AudioPolicyService::AudioPolicyClient

status_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的分析。


阅读(3862) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~