音频 Alsa、Framework及Android

目录

1 Alsa、Framework及Android

1.1 ALSA架构简介图1

1.2 ALSA架构简介图 2

1.3 ALSA架构简介图 3

1.4 ALSA架构简介图 4

1.5 ALSA架构简介图 5

1.6 ALSA架构简介图 6

1.8 音频代码


1 Alsa、Framework及Android

目前,linux系统常用的音频驱动有两种形式:alsa和oss。Alsa:现在是linux下音频驱动的主要形式,与简单的oss兼容。oss:过去的形式音频设备接口包括PCM、IIS和AC97等,分别使用于不同的应用场合。针对音频设备,linux内核中包含了3类音频设备驱动框架,OSSALSAASoC,OSS包含dsp和mixer字符设备接口,在用户空间的编程中,完全使用文件的操作;ALSA以card和组件(PCM 、mixer等)为主线,在用户空间的编程中不使用文件接口而使用alsa lib;ASoC则是ALSA在SoC方面的演变,他建立在ALSA之上,将ALSA驱动中的CPU相关的代码和Codec相关的代码进行了分离。

在音频设备驱动中,几乎必须使用DMA,而DMA的缓冲区会被分割成一个一个的段,每次DMA操作其中的一段,OSS驱动的阻塞读写具有流程控制能力,在用户空间不需要进行流量方面的定时工作,但是他需要及时的写(播放)和读(录音),以免出现缓冲区的underflow或overflow。ALSA和ASoC的流控由ALSA的核心层处理,底层驱动仅以trigger()、pointer()等方法进行配合。

在声卡的驱动中一种是OSS:open sound system(开放声音系统),一种是ALSA: Advanced Linux Sound Architecture(先进Linux声音架构)。OSS是一个商业声卡驱动程序,需要花钱购买。一般我们现在使用的是ALSA的声音架构,ALSA包括对声卡的支持和驱动。嵌入式微控制器/DSP中集成了PCM(脉冲编码调制接口)、IIS或者AC97音频接口。通过这些接口外部的音频解码器可以实现声音的AD和DA转换。

ALSA具有更加友好的编程接口,并且完全兼容与OSS,对应用程序员来讲无疑是一个更好的选择。ALSA系统包括驱动包alsa-drvier开发包alsa-libs开发包插件alsa-libplugins设置管理工具包alsa-utils其他声音相关处理小程序包alsa-tools特殊音频固件支持包alsa-firmwareOSS接口模拟层工具alsa-oss共7个子项目,其中只有驱动包是必须的。ALSA的基本特征如下:

1、对所有音频接口的高效支持,从普通用户的声卡到专业级别多路音频设备;

2、支持多种盛开设备、声卡驱动完全模块化设计;

3、支持SMP 和多线程。

4、支持应用开发库(alsa-lib)以简化应用程序开发。为程序设计提供了简单、方便,并且拥有有高级的效果和功能;

5、支持旧版本的OSS API 结口,能为大多数的OSS应用程序提供兼容;OSS是一个商业性的驱动,OSS有一个简装本的代码已经移入内核和ALSA,其中alsa-oss就是;OSS公司据说目前已经并不存在了;我们没有必要用OSS 公司提供的商业版本;用ALSA和OSS简装版足够;

目前ALSA内核提供的用户空间接口有:

信息接口(Information Interface,/proc/asound)

控制接口(Control Interface,/dev/snd/controlCX): 提供管理声卡注册和请求可用设备的通用功能。

混音器接口(Mixer Interface,/dev/snd/mixerCXDX)

PCM接口(PCM Interface,/dev/snd/pcmCXDX):管理数字音频回放(playback)和录音(capture)的接口。它是开发数字音频程序最常用到的接口。

Raw MID接口(Raw MIDI Interface,/dev/snd/midiCXDX):支持MIDI(Musical Instrument Digital Interface),标准的电子乐器。这些API提供对声卡上MIDI总线的访问。这个原始接口基于MIDI事件工作,由程序员负责管理协议以及时间处理。

音序器接口(Sequencer Interface,/dev/snd/seq)

定时器接口(Timer Interface,/dev/snd/timer):为同步音频事件提供对声卡上时间处理硬件的访问。

ASoC驱动的组成:

Codec驱动(编解码器驱动):这一部分只关心Codec本身,与CPU平台相关的特性不由此部分操作;

平台驱动(CPU驱动):只关心CPU本身,不关系Codec,主要处理两个问题:DMA引擎、SoC集成的PCM、IIS、AC97数字接口控制

板驱动(machine机器驱动):将平台驱动和Codec驱动绑定在一起,描述了板一级的硬件特性。

ALSA由许多声卡的声卡驱动程序组成,同时它也提供一个称为libasound的API库。应用程序开发者应该使用libasound而不是内核中的ALSA接口。因为libasound提供最高级并且编程方便的编程接口。并且提供一个设备逻辑命名功能,这样开发者甚至不需要知道类似设备文件这样的低层接口。相反,OSS/Free驱动是在内核系统调用级上编程,它要求开发者提供设备文件名并且利用ioctrl来实现相应的功能。为了向后兼容,ALSA提供内核模块来模拟OSS,这样之前的许多在OSS基础上开发的应用程序不需要任何改动就可以在ALSA上运行。另外,libaoss库也可以模拟OSS,而它不需要内核模块。ALSA包含插件功能,使用插件可以扩展新的声卡驱动,包括完全用软件实现的虚拟声卡。ALSA提供一系列基于命令行的工具集,比如混音器(mixer),音频文件播放器(aplay),以及控制特定声卡特定属性的工具。

API库使用逻辑设备名而不是设备文件。设备名字可以是真实的硬件名字也可以是插件名字。硬件名字使用hw:i,j这样的格式。其中i是卡号,j是这块声卡上的设备号。第一个声音设备是hw:0,0.这个别名默认引用第一块声音设备并且在本文示例中一真会被用到。插件使用另外的唯一名字。比如plughw:,表示一个插件,这个插件不提供对硬件设备的访问,而是提供像采样率转换这样的软件特性,硬件本身并不支持这样的特性。

每个声卡都有一个硬件缓存区来保存记录下来的样本。当缓存区足够满时,声卡将产生一个中断。内核声卡驱动然后使用直接内存(DMA)访问通道将样本传送到内存中的应用程序缓存区。类似地,对于回放,任何应用程序使用DMA将自己的缓存区数据传送到声卡的硬件缓存区中。这样硬件缓存区是环缓存。也就是说当数据到达缓存区末尾时将重新回到缓存区的起始位置。ALSA维护一个指针来指向硬件缓存以及应用程序缓存区中数据操作的当前位置。应用程序缓存区的大小可以通过ALSA库函数调用来控制。缓存区可以很大,一次传输操作可能会导致不可接受的延迟,我们把它称为延时(latency)。为了解决这个问题,ALSA将缓存区拆分成一系列周期(period)(OSS/Free中叫片断fragments).ALSA以period为单元来传送数据。一个周期(period)存储一些帧(frames)。每一帧包含时间上一个点所抓取的样本。对于立体声设备,一个帧会包含两个信道上的样本。一个缓存区分解成周期,然后是帧,然后是样本。包含一些假定的数值。左右信道信息被交替地存储在一个帧内。这称为交错(interleaved)模式。在非交错模式中,一个信道的所有样本数据存储在另外一个信道的数据之后。当一个声卡活动时,数据总是连续地在硬件缓存区和应用程序缓存区间传输。但是也有例外。在录音例子中,如果应用程序读取数据不够快,循环缓存区将会被新的数据覆盖。这种数据的丢失被称为overrun.在回放例子中,如果应用程序写入数据到缓存区中的速度不够快,缓存区将会"饿死"。这样的错误被称为"underrun"。在ALSA文档中,有时将这两种情形统称为"XRUN"。适当地设计应用程序可以最小化XRUN并且可以从中恢复过来。

1.1 ALSA架构简介图1

ALSA是Advanced Linux Sound Architecture,高级Linux声音架构的简称,它在Linux操作系统上提供了音频和MIDI(Musical Instrument Digital Interface,音乐设备数字化接口)的支持。它包含API 库和工具、内核驱动集合,对Linux声音进行支持。 ALSA 包含一系列内核驱动对不同的声卡进行支持,还提供了libasound的API库。用这些进行写程序不需要打开设备等操作,所以编程人员在写程序的时候不会被底层的东西困扰。

ALSA自带的应用程序是alsa-utils工具包,包括aplay、alsamixer等。aplay用于在ASLA上播放音频。alsamixer用于改变音频信号的音量。

alsa-lib是用户空间的函数库,提供了libasound.so给应用程序使用,应用程序应包含头文件asoundlib.h。这个库通过提供封装函数(ALSA-API),使ALSA应用程序不需要涉及具体硬件,编写起来更容易。alsa-lib中有control,timer,dmix,pcm等,都是以插件(plugin)的形式存在的。alsa-lib通过硬件访问层的系统调用与内核层进行交互。

alsa-driver是音频设备的alsa内核部分的驱动。集成在内核里面,大多是以模块的方式存在。可分为三层。

      (1)最底层是硬件操控层,负责实现硬件操纵访问的功能,这也是声卡驱动程序中用户需实现的主要部分;

      (2)中间层是ASLA驱动的核心部分,它由各种功能的音频设备组件构成,为用户提供了一些预定义组件(如PCM、AC97、音序器和控制器等),另外用户也可以自行定义设备组件;

      (3)驱动的最上层是声卡对象描述层,它是声卡硬件的抽象描述,内核通过这些描述可以得知该声卡硬件的功能、设备组件和操作方法等。

1.2 ALSA架构简介图 2

下图是从代码的角度体现了alsa-lib和alsa-driver及hardware的交互关系。用户层的alsa-lib通过操作alsa-driver创建的设备文件/dev/snd/pcmC0D0p等对内核层进行访问。内核层的alsa-drivier驱动再经由sound core对硬件声卡芯片进行访问。从而实现了app、alisa-lib、alsa-driver、hardware的操作。图中右上角OSS相关部分是为了兼容OSS。

1.3 ALSA架构简介图 3

声卡芯片的硬件驱动程序实际上是alsa-driver的一部分,但是在本文档中,为了明示层次关系,将这两个分开对待。将硬件驱动程序叫做device-driver(设备驱动), alsa-driver的其它部分叫做alsa-driver(alsa驱动)。

硬件驱动被insmod后,应用程序就可以调用ALSA-lib的API函数播放声音。下图是从应用程序开始,到我们的编写设备驱动程序的调用过程。从应用程序角度看,ASLA的操作分为两部分,打开及关闭是一部分,写入数据是另一部分。

当声卡name使用”default”时,pcm作为dmix的从设备存在,应用程序直接和dmix的相关函数打交道。dmix混合数据后,直接写到mmap映射的地址中。

从设备驱动程序角度看,声卡核心驱动可以分为三个主要部分:

    (1) 模块初始化和退出部分。

    (2) 播放以及停止部分。

    (3) 中断处理部分。

   而从应用程序的角度向下看,这三部分分别在insmod、打开声卡和写入数据时被关联。

1.4 ALSA架构简介图 4

1.5 ALSA架构简介图 5

Android的Audio系统从上层应用到底层驱动大致可以分为Audio的JAVA层, JNI层,框架层, Flinger层, HAL层以及Kernel层。

1.6 ALSA架构简介图 6

整个Android系统有关声音的操作,主要分为图所示的几个层次。其中C/C++框架、Audio本地API、JAVA框架属于Android已经定义的Audio框架,对HAL层有明确的接口要求,HAL层将Android定义的Audio的接口基于kernel实现。

1.8 音频代码

1.8.1 App层代码:                  \packages\apps\Phone\src\com\android\phone

                                            \packages\apps\Music\src\com\android\music

                                            \packages\apps\SoundRecorder\src\com\android\soundrecorder

1.8.2 java层代码:                  \frameworks\base\media\java\android\media

与Audio相关的Java包是android.media,主要包含文件:

         AudioManager.java:主要负责Audio系统的管理,向下会调用AudioService.java

         AudioService.java:主要负责Audio系统的相关服务,向下会调用AudioSystem.java

         AudioSystem.java:主要负责Audio系统的总体控制

         AudioTrack.java:主要负责Audio系统的输出环节

         AudioRecord.java:主要负责Audio系统的输入环节

         简单来说,Android的Audio主要完成三个工作:Audio控制(包括音量,音频策略等),Audio播放和Audio录音。

1.8.3 jni层代码:                    \frameworks\base\media\jni

Audio通过JNI向Java层提供接口,在Java层可以通过JNI接口来完成Audio系统大部分操作。这部分代码会生成库libandroid_runtime.so,Audio的JNI是其中的一部分。JNI层主要包括了三个文件:

         android_media_AudioSystem.cpp负责Audio系统的总体控制

         android_media_AudioTrack.cpp负责Audio系统的输出环节

         android_media_AudioRecord.cpp负责Audio系统的输入环节

1.8.4 cpp层代码:                  \frameworks\base\media\libmedia

头文件路径:mydroid\frameworks\base\include\media

源代码路径:mydroid\frameworks\base\media\libmedia

Audio本地框架是Media库的一部分,它会被编译成库libmedia.so,提供Audio部分的

接口(包括基于Binder的IPC机制),由下层的本地代码去实现。、

1.8.5 audioflinger层代码:  \frameworks\base\services\audioflinger

Android的音频系统有两大服务:AudioFlinger和AudioPolicyService。这两大服务都在系统启动时通过MediaSever加载,加载的路径:

mydroid\frameworks\base\media\mediaserver\main_mediaserver.cpp

AudioFlinger层的内容会编译成库libaudioflinger.so。AudioFlinger是Audio系统的中间层,在系统中起服务的作用,向上通过IAudioFlinger接口提供服务,向下访问AudioHardware,实现输出音频数据,控制音频参数。另外,AudioFlinger还为libmedia提供Audio部分接口的实现。

AudioPolicyService主要完成以下功能:JAVA应用层通过JNI,经由IAudioPolicyService接口,访问AudioPolicyService提供的服务。

         ·输入输出设备的连接状态。

       ·系统的音频策略(strategy)的切换。

    ·音量/音频参数的设置。

AudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音频策略(strategy)管理,输入输出设备管理。

1.8.6 hal层代码:                   \hardware\alsa_sound

                                            \hardware\mx5x\modules\alsa

代码路径:mydroid\hardware\libhardware_legacy\include\hardware_legacy

主要函数:AudioHardwareBase.h

AudioHardwareInterface.h

AudioHardwareInterface.h中定义了3个类:

AudioStreamOut

AudioStreamIn

AudioHardwareInterface

1.8.7 Driver层代码:             \kernel_imx\sound\soc\imx(machine driver)

                                            \kernel_imx\sound\soc\codecs(codec driver)

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android凭借其开源,良好的用户体验,高性价比,庞大的应用程序等优势迅速发展起来并保持强劲的发展势头。如今Android智能手机、Android平板电脑等移动产品已走入人们的日常生活,成为人们通讯、娱乐的重要工具。本设计以malata采用RK2918方案的Android平板电脑项目为背景,主要任务是设计和实现Android平板电脑的音频系统,为广大平板用户提供良好的音频体验。 ALSA(Advanced Linux Sound Architecture,高级Linux声音架构)在Linux操作系统上提供了音频和MIDI(Musical Instrument Digital Interface,音乐设备数字化接口)的支持。它的主要特性包括:高效地支持从消费类入门级声卡到专业级音频设备所有类型的音频接口,完全模块化的设计,支持对称多处理和线程安全,对OSS(Open Sound System,开放声音系统)的向后兼容,以及提供了用户空间的alsa-lib库来简化应用程序的开发[1]。基于ALSA音频系统能够很好的适应硬件的多样性,因此Android设备厂商能够更灵活地根据不同需求选择不同的音频编解码芯片。ALC5625是一款高度集成低功耗高保真的带I2S/PCM接口并具有多路输入输出的音频编解码器,可满足本次设计的各项需求。 基于ALSA的Andorid音频系统拥有一个标准和健全的架构,自上而下由Audio应用程序、Audio Java框架层、Audio本地框架层、AudioFlinger、Audio硬件抽象层、alsa-lib和底层Audio驱动几个部分组成。本文分析音频系统架构的各个层次,并着重阐述ALSAAndroid音频系统中的应用以及Audio驱动的详细实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值