Android Audio System 架构初探:概述

来源:互联网 发布:阿里云.api 编辑:程序博客网 时间:2024/05/16 05:21

1     Audio系统

1.1     一些基本概念

采样率

用一堆离散的数字表示真实世界里连续的声音信号,需要对其进行采样,理论基础是奈奎斯特采样定理。采样率的单位是赫兹,就是说一秒有多少个采样,一般数字音频的采样率通常为8k~48k,一些hifi系统的采样率可以达到192k。

奈奎斯特采样定理:当对被采样的模拟信号进行还原时,其最高频率只有采样频率的一半。

位深:

一个系统用多少个bit来表示一个采样,就说这个系统的位深为多少。位深代表了采样精度,一般数字音频系统的位深为16bit,一些hifi系统可以达到24bit或32bit(整型或float型)。

编码方式

用数字描述模拟信号的方式,一般为PCM,即脉冲编码调制。目前几乎所有的系统都是基于这种编码实现的。

有些hifi系统也会用到DSD(Pulse-densitymodulation)编码,信号表现为delta-sigma编码。采样率为2.8224M但是采样精度是1bit(2.8224M=44.1K*64)。据说此种编码更接近模拟信号,对原声的还原度最高。

比如,  DSD二进制表达是这样的:

0101011011110111111111111111111111011111101101101010100100100000010000000000000000000001000010010


声压级:

人体有个很有趣的现象,就是人体的各种感官(听觉,视觉,触觉)的感知和刺激的物理量之间是呈对数关系的。声压级以符号SPL表示,其定义为将待测声压有效值p(e)与参考声压p(ref)的比值取常用对数,再乘以20,即:SPL=20LOG(10)[p(e)/p(ref)]。其单位是分贝(dB)。在系统中,声压级不仅和音量设置有关,还和音源有关。

 

1.2     系统框图

图表1Audio系统架构

 

 

图表1Audio Framework架构

数据流:

录音/播放数据流

Android系统播放数据流

硬件组成

 

 

1.3     进程和线程

1.3.1       MediaServer进程

可执行文件/system/bin/mediaserver运行生成的进程,看该可执行文件的main函数。

main_mediaserver.cpp(frameworks\av\media\mediaserver)

int main(int argc __unused,char**argv)

{

   pid_t childPid;

   doLog = true;

    if (doLog&& (childPid=fork())!= 0){

       sp<ProcessState>proc(ProcessState::self());

       MediaLogService::instantiate();

       ProcessState::self()->startThreadPool();

    }

    else

    {

       sp<ProcessState>proc(ProcessState::self());

       int status =hwservices_get_module("libaudioflinger","audioflinger");

       if (status!=0)

       {

           AudioFlinger::instantiate();

       }

       MediaPlayerService::instantiate();

       AudioPolicyService::instantiate();

       SoundTriggerHwService::instantiate();

       AudioOmService::instantiate();

       CameraService::instantiate();

       PostCameraService::instantiate();

       registerExtensions();

       ProcessState::self()->startThreadPool();

       IPCThreadState::self()->joinThreadPool();

    }

}

Fork的返回值:On success, the PID of thechild process is returned in the parent, and 0 is returned in the child. Onfailure, -1 is returned in the parent, no child process is created,and errno is set appropriately.wait, waitpid, waitid - wait forprocess to change state

 

图表17mediaserver里的线程

这是在播放一首mp3时的截屏。下面逐条分析每个线程:

1.  /system/bin/mediaserver,系统解析init.rc时fork出来的主线程,启动进入main_mediaserver.cpp中的main函数。

2.  ApmTone,APS启动时创建的线程

3.  ApmAudio,APS启动时创建的线程

4.  ApmOutput,APS启动时创建的线程

5.  Mediaserver,不知

6.  AudioOutput_2和AudioOut_3, 使用output 2和3的playbackthread

7.  FastMixer, FastMixer线程

8.  HwApmCommand,华为定制的AudioPolicyManager命令处理线程

9.  AudioTrack,播放mp3的AudioTrack线程

10. TimeEventQueue,AwesomePlayer的异步事件线程

11. Gle.mp3.decoder,创建SoftCompoent时创建的解码线程,进行耗时操作。

12.  OMXCallbackDisp, OMX在allocateNode时创建的异步收发消息EMPTY_BUFFER_DONE,FILL_BUFFER_DONE的线程

1.3.2       system_server进程

1.             AudioService。

SystemServer添加AudioService到ServiceManager中,在AudioService的构造函数中,创建一个线程AudioSystemThread,名字就叫“AudioService”,它通过handler不停的接收消息。

2.             SoundPool

App播放短促频繁的声音时使用的功能。

3.             SoundPoolThread

0 0
原创粉丝点击