`
mmdev
  • 浏览: 12893357 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Android Audio相关 AudioFlinger类

 
阅读更多
1、继承自BinderService<AudioFlinger>和BnAudioFlinger。


2、定义了一些枚举常量。
hardware_call_state : AUDIO_HW_OUTPUT_OPEN等
track_state : RESUMING等


3、类 PlaybackThread : public ThreadBase中用到的常量:
enum type {
MIXER,
DIRECT,
DUPLICATING
};


enum mixer_state {
MIXER_IDLE,
MIXER_TRACKS_ENABLED,
MIXER_TRACKS_READY
};


4、构造函数中:
调用函数AudioHardwareInterface::create()创建一个AudioHardware,之后的实现基本上是调用该AudioHardware对象来完成的。


5、有两个DefaultKeyedVector类型的成员变量:


mPlaybackThreads:用于记录播放线程。
mRecordThreads:用于记录录音线程。


DefaultKeyedVector< int, sp<PlaybackThread> > mPlaybackThreads;
DefaultKeyedVector< int, sp<RecordThread> > mRecordThreads;


函数checkPlaybackThread_l和函数checkRecordThread_l分别将mPlaybackThreads和mRecordThreads中记录的线程按编号返回。
函数checkMixerThread_l返回的也是mPlaybackThreads中记录的线程,不过将返回值转换为了MixerThread类型的指针。


6、函数createTrack中,


首先调用函数checkPlaybackThread_l获取播放线程。output是调用函数createTrack时传入的参数。
PlaybackThread *thread = checkPlaybackThread_l(output);


然后调用PlaybackThread的函数createTrack_l创建一个track。
sp<PlaybackThread::Track> track;
track = thread->createTrack_l(client, streamType, sampleRate, format,
channelCount, frameCount, sharedBuffer, lSessionId, &lStatus);


然后以track为参数创建一个rackHandle
sp<TrackHandle> trackHandle;
trackHandle = new TrackHandle(track);


最后将trackHandle作为返回值返回。


7、接下来几个函数的实现方法类似,都是先调用函数checkPlaybackThread_l获取播放线程。output是各函数的输入参数。
PlaybackThread *thread = checkPlaybackThread_l(output);
然后调用PlaybackThread的相应函数实现功能。
这样的函数包括:
sampleRate
channelCount
format
frameCount
latency


8、接下来有两个实现方法类似的函数,setMasterVolume和setMode。
都是首先调用mAudioHardware的对应函数,然后再调用mPlaybackThreads的对应函数。
例如,函数setMasterVolume:
mAudioHardware->setMasterVolume(value)
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setMasterVolume(value);


可见,对mAudioHardware的函数的调用完成对硬件的操作,对mPlaybackThreads的函数的调用修改了audioflinger层保存的状态。


9、接下来的两个函数setMicMute和getMicMute,都是通过调用mAudioHardware的函数来实现的。


10、函数setMasterMute中,
遍历mPlaybackThreads中的各个线程,并分别调用他们的setMasterMute函数。
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setMasterMute(muted);


由此看来,MasterMute控制所有的播放线程。


11、接下来两个函数masterVolume和masterMute,分别将对应 的成员变量返回。


12、接下来是函数setStreamVolume,
如果传入的output不为0,调用函数checkPlaybackThread_l获取对应的线程,然后调用该线程的setStreamVolume函数。
否则,遍历mPlaybackThreads,分别调用各线程的setStreamVolume函数。


13、函数setStreamMute,
遍历mPlaybackThreads,分别调用各线程的setStreamMute函数。


14、函数streamVolume中,
传入的output参数若不为0,调用函数checkPlaybackThread_l获取对应的线程,然后调用该线程的streamVolume函数,并将结果作为返回值返回。
若传入的output为0,取成员变量数组mStreamTypes对应stream的volume,并返回。
成员变量数组mStreamTypes的定义:
PlaybackThread::stream_type_t mStreamTypes[AudioSystem::NUM_STREAM_TYPES];


15、函数streamMute,取成员变量数组mStreamTypes对应stream的mute,并返回。


16、函数isStreamActive,遍历mPlaybackThreads,分别调用各线程的isStreamActive,遇到函数isStreamActive返回true时,即退出循环并返回true。
如果遍历结束,没有true的情况,即返回false。


17、函数setParameters中,
如果ioHandle为0,即表示参数是对整个audio hardware interface有效的,调用mAudioHardware的函数setParameters,并将结果返回。
result = mAudioHardware->setParameters(keyValuePairs);
否则,调用函数checkPlaybackThread_l和checkRecordThread_l获取ioHandle对应的线程,然后调用线程的setParameters函数。


18、函数getParameters的处理,与函数setParameters类似。
如果ioHandle为0,调用mAudioHardware的函数getParameters,并返回。
否则,调用checkPlaybackThread_l和checkRecordThread_l,获取对应的线程,并调用对应线程的getParameters函数。


19、函数getInputBufferSize,直接调用mAudioHardware的getInputBufferSize函数,并返回。


20、函数getInputFramesLost,调用checkRecordThread_l获取录音线程,然后调用线程的getInputFramesLost函数。


21、函数setVoiceVolume,直接调用mAudioHardware的setVoiceVolume函数,并将结果返回。


22、getRenderPosition函数,
调用函数checkPlaybackThread_l获取播放线程,然后调用播放线程的getRenderPosition函数并将结果返回。

23、函数registerClient,

首先获取调用pid:
    int pid = IPCThreadState::self()->getCallingPid();
创建一个NotificationClient对象:
        sp<NotificationClient> notificationClient = new NotificationClient(this,
                                                                            client,
                                                                            pid);
调用mNotificationClients的add函数,实现notificationClient对象的注册:
        mNotificationClients.add(pid, notificationClient)
遍历mPlaybackThreads,分别调用各线程的sendConfigEvent函数发送AudioSystem::OUTPUT_OPENED事件。
遍历mRecordThreads,分别调用各线程的sendConfigEvent函数,发送AudioSystem::INPUT_OPENED事件。

24、函数removeNotificationClient,
调用mNotificationClients的removeItem函数,删除相应的item。

25、函数audioConfigChanged_l,
遍历mNotificationClients,分别调用各notification client的ioConfigChanged函数。
函数中没有做AudioFlinger::mLock处理,调用该函数时必须做AudioFlinger::mLock处理。

26、函数removeClient_l,
调用mClients的函数removeItem,删除item。
在函数createTrack,openRecord和createEffect中会调用mClients的函数add追加item。

分享到:
评论

相关推荐

    Android 12 AudioFlinger 分析(RK3588)

    Android 12 AudioFlinger 分析(RK3588)

    Android P Audio系统笔记:AudioPolicy&AudioFlinger初始化

    AudioFlinger和AudioPolicy两者是Android Audio框架层最主要的两个服务,他们两个是Android框架层的本地服务,在init.rc中启动; AudioPolicyManager负责音频策略定制者,说白了就相当于Audio系统的司令。 Audio...

    android audioflinger.pdf

    android audioflinger.pdf

    Android深入浅出之AudioFlinger

    android音频子系统之AudioFlinger深入分析

    Android深入浅出之Audio 第二部分 AudioFlinger分析

    NULL博文链接:https://innost.iteye.com/blog/875435

    安卓audio-audioflinger、audiopolicy策略加载

    最全策略加载,一片文档让你熟悉整个安卓audio framework

    audio上层框架介绍

    IAudioFlinger.cpp是AudioFlinger.cpp给上层提供的接口,降低了耦合性,同样对于AudioPolicyService也是如此。即使AudioFlinger.cpp里面的内容发生变化,只要与IAudioFlinger.cpp预留的接口保持一致,上层的代码就不...

    android Audio ALSA框架分析

    从框图中可以看出 android 对于 java 层一共提供 3 个接口,分别 ...AudioFlinger 层相同步,之后调用到 AudioHardware ,其中提供的接口主要 AudioStreamOut以及AudioStreamin。最终将进入Linux内核调用到ALSA。

    Android音频详解.pdf

    这个文档是我整理别人博客的,写的非常的不错,通俗易懂,相对来说还是比较全面,讲了linux下的声卡,Android音频 , AudioPolicyService, AudioFlinger, AudioTrack这些都有详细的讲解,然后我也做了书签,方便...

    android audio system

    (2)AudioFlinger 作为 Audio 系统的中间层; (3)Audio 的硬件抽象层提供底层支持; (4)Audio 接口通过 JNI 和 Java 框架提供给上层。 Audio 系统的各个层次接口主要提供了两方面功能:放音(Track)和录音(Recorder) 。

    Android 9 Audio系统笔记:音频路由实现——从AudioTrack到audiohal

    上一篇介绍了AudioFlinger的初始化,接下来对音频路由进行介绍。注意,本文主要介绍动态路由,即汽车音频路由的常规方式。针对Android原生路由策略不做深入分析。 什么是音频路由?如何实现音频路由?如何定制音频...

    Android端AudioTrack以及OpenSL ES结合ffmpeg播放mp3文件

    使用Android端AudioTrack以及OpenSL ES结合ffmpeg播放mp3文件

    Audio Framework.vsdx

    AudioPolicyService和AudioFLinger、AudioPolicyManager、AudioPolicyClient之间的调用关系

    Android-Audio相关代码调用流程

    https://blog.csdn.net/tujidi1csd/article/details/127408058 中所有图片的源文件。 使用draw.io画的。

    android系统原理及开发要点详解

     第5章“Android的Java虚拟机和Java环境”,这是介于本地和Java层之间的相关内容,主要介绍Android的Java虚拟机Dalvik的基本概念、Android Java程序的环境、JNI的使用方法,以及Java框架的启动流程等。  第6章...

    基于ALSA的Android音频系统设计与实现

    基于ALSA的Andorid音频系统拥有一个标准和健全的架构,自上而下由Audio应用程序、Audio Java框架层、Audio本地框架层、AudioFlinger、Audio硬件抽象层、alsa-lib和底层Audio驱动几个部分组成。本文分析音频系统架构...

    A Completely Covert Audio Channel in Android.pdf

    inaudible call, without any visual or audio indication given to the victim. We provide a detailed analysis of our attack, and we suggest possible counter measures to thwart similar attacks.

    《深入理解Android:卷I》试读本

    第7章对Audio系统进行了深入的分析,尤其是AudioTrack、AudioFlinger和AudioPolicyService等的工作原理。第8章深入讲解了Surface系统的实现原理,分析了Surface与Activity之间以及Surface与SurfaceFlinger之间的关系...

    深入理解Android:卷I--详细书签版

    audio系统进行了深入的分析,尤其是audiotrack、audioflinger和audiopolicyservice等的工作原理。第8章深入讲解了surface系统的实现原理,分析了surface与activity之间以及surface 与surfaceflinger之间的关系、...

    Android技术内幕.系统卷(扫描版)

    6.4.1 audioflinger实现 /328 6.4.2 surfaceflinger实现 /341 6.5 小结 /353 第7章 硬件抽象层的原理与实现 /354 7.1 硬件抽象层的实现原理 /355 7.1.1 android hal构架 /355 7.1.2 android hal的实现 /357 7.2 ...

Global site tag (gtag.js) - Google Analytics