Android的Audio系统(二)
1.3 Audio的硬件抽象层 1.3.1 Audio硬件抽象层的接口定义 Audio的硬件抽象层是AudioFlinger和Audio硬件的接口,在各个系统的移植过程中可以有不同的实现方式。Audio硬件抽象层的接口路径为: hardware/libhardware_legacy/include/hardware/ 其中主要的文件为:AudioHardwareBase.h和AudioHardwareInterface.h。 Android中的Audio硬件抽象层可以基于Linux标准的ALSA或OSS音频驱动实现,也可以基于私有的Audio驱动接口来实现。 在AudioHardwareInterface.h中定义了类:AudioStreamOut、AudioStreamIn和AudioHardwareInterface,AudioStreamOut和AudioStreamIn分别对应了音频的输出环节和输入环节,其中负责数据流的接口分别是wirte()和read(),参数是一块内存的指针和长度;另外还有一些设置和获取接口。在这个AudioHardwareInterface接口中,使用openOutputStream()和openInputStream()函数分别获取AudioStreamOut和AudioStreamIn两个类,它们作为音频输入/输出设备来使用。此外,AudioHardwareInterface.h定义了C语言的接口来获取一个AudioHardware Interface类型的指针。 extern"C" AudioHardwareInterface* createAudioHardware(void); 如果实现一个Android的硬件抽象层,则需要实现AudioHardwareInterface、AudioStream Out和AudioStreamIn三个类,将代码编译成动态库libauido.so。AudioFlinger会连接这个动态库,并调用其中的 createAudioHardware()函数来获取接口。 在AudioHardwareBase.h中定义了类:AudioHardwareBase,它继承了Audio HardwareInterface,显然继承这个接口也可以实现Audio的硬件抽象层。 1.3.2 AudioFlinger中自带Audio硬件抽象层实现 在AudioFlinger中可以通过编译宏的方式选择使用哪一个Audio硬件抽象层。这些Audio硬件抽象层既可以作为参考设计,也可以在没有实际的Audio硬件抽象层(甚至没有Audio设备)时使用,以保证系统的正常运行。AudioDumpInterface.h和AudioDumpInterface.cpp是一个提供了Dump功能的Audio硬件抽象层,它所起到的作用就是将输出的Audio数据写入到文件中。AudioDumpInterface并不是为了实际的应用使用的,而是为了调试使用的类。当进行音频播放器调试时,有时无法确认是解码器的问题还是Audio输出单元的问题,这时就可以用这个类来替换实际的Audio硬件抽象层,将解码器输出的Audio的PCM数据写入文件中,由此可以判断解码器的输出是否正确。 1.3.3 Audio硬件抽象层的真正实现 实现一个真正的Audio硬件抽象层,需要完成的工作和实现以上的硬件抽象层类似。 例如:可以基于Linux标准的音频驱动:OSS(Open Sound System)或者ALSA(Advanced Linux Sound Architecture)驱动程序来实现。 对于OSS驱动程序,实现方式和前面的AudioHardwareGeneric类似,数据流的读/写操作通过对/dev/dsp设备的读/写来完成;区别在于OSS支持了更多的ioctl来进行设置,还涉及通过/dev/mixer设备进行控制,并支持更多不同的参数。 对于ALSA驱动程序,实现方式一般不是直接调用驱动程序的设备节点,而是先实现用户空间的alsa-lib,然后Audio硬件抽象层通过调用alsa-lib来实现。 在实现Audio硬件抽象层时,对于系统中有多个Audio设备的情况,可由硬件抽象层自行处理setRouting()函数设定,例如,可以选择支持多个设备的同时输出,或者有优先级输出。对于这种情况,数据流一般来自AudioStreamOut::write()函数,可由硬件抽象层确定输出方法。对于某种特殊的情况,也有可能采用硬件直接连接的方式,此时数据流可能并不来自上面的write(),这样就没有数据通道,只有控制接口。 Audio硬件抽象层也是可以处理这种情况的。 参考文献:《Android系统原理及开发要点详解》电子工业出版社 韩超 梁泉 著 |