Android Audio介绍

Android Audio介绍,第1张

概述开始这篇文章之前,可以先了解<Linux音频编程>1.架构在Android中,Audio整体架构如下2.JavaAudio在Java层把Audio从功能上分为三类接口AudioService:负责的是Audio系统的综合管理功能,包括音量控制、音频IO设备的管理、音频焦点机制AudioTrack:负责音频数据的输出,即

开始这篇文章之前,可以先了解<Linux音频编程>

1. 架构

在AndroID中,Audio整体架构如下

2. Java Audio

在Java层把Audio从功能上分为三类接口

AudioService:   负责的是Audio系统的综合管理功能, 包括音量控制、音频IO设备的管理、音频焦点机制AudioTrack:     负责音频数据的输出,即播放AudioRecorder:  负责音频数据的输出和输入,即录制
2.1 AudioService

AudioService由SystemServer启动,实现了IAudioService的Bn端;AudioManager则实现了IAudioService的Bp端

AudioService的功能实现依赖Java AudioSystem类,AudioSystem是Native AudioSystem在Java层的封装和代理

IAudioService  -   frameworks/base/media/java/androID/media/IAudioService.aIDl)

SystemServer::startOtherServices()    SystemServiceManager::startService(AudioService.lifecycle.class)        new AudioService()        AudioService::onStart()            publishBinderService(Context.AUdio_SERVICE, new AudioService());                // 向servicemanager注册服务                ServiceManager.addService( , , , )        AudioService::onBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY)            AudioService::systemReady()                AudioHandler::handleMessage(MSG_SYstem_READY)                    AudioService::onSystemReady()                        AudioHandler::onLoadSoundEffects()                        // Bluetooth releated config                        AudioService::onIndicateSystemReady()                            // 位于androID_media_AudioSystem.cpp                            androID_media_AudioSystem_systemReady()                                // 位于AudioSystem.cpp                                AudioSystem::systemReady()

AudioTrack通过JNI的方式使用androID_media_AudioTrack.cpp封装的接口,进而使用到Native AudioTrack提供的接口

AudioRecord通过JNI的方式使用androID_media_AudioRecord.cpp封装的接口,进而使用到Native AudioRecord提供的接口

3. Native Audio3.1 audioserver

Native Audio服务在AndroID N之前存在于mediaserver中,AndroID N之后由audioserver来启动

audioserver主要启动了两个Native binder服务

- audioflinger:        音频系统策略的执行者, 负责音频流设备的管理及音频流数据的处理传输, 由libaudioflinger实现具体功能- AudioPolicyService : 音频系统策略的制定者, 负责音频设备切换的策略抉择、音量调节策略等, 由libaudiopolicyservice实现具体功能

audioserver的启动的详细过程如下

/* * frameworks/av/media/audioserver/audioserver.rc */# cat audioserver.rcservice audioserver /system/bin/audioserver    class core    user audioserver    onrestart restart vendor.audio-hal-2-0    onrestart restart audio-hal-2-0/* * Code:   frameworks/av/media/audioserver/main_audioserver.cpp * Output: /system/bin/audioserver */main()    audioflinger::instantiate()        BinderService::instantiate()            BinderService::publish()                IServiceManager sm = defaultServiceManager()                sm::addService("media.audio_flinger", new audioflinger())                    audioflinger::onFirstRef()                        new PatchPanel(this)                        gaudioflinger = this;    AudioPolicyService::instantiate()                sm::addService("media.audio_policy", new AudioPolicyService())                    AudioPolicyService::onFirstRef()                        // Tone播放线程                        new AudioCommandThread("ApmTone", this)                            AudioCommandThread::onFirstRef()                                Thread::run()                                    AudioCommandThread::threadLoop()                        // Audio命令线程                        new AudioCommandThread("ApmAudio", this)                        // 输出命令线程                        new AudioCommandThread("ApmOutput", this)                        new AudioPolicyClIEnt(this)                        createAudioPolicyManager()                            new AudioPolicyManager(mAudioPolicyClIEnt)                                AudioPolicyManager::AudioPolicyManager()                                    /*                                     * 当定义了USE_XML_AUdio_POliCY_CONF = 1                                     * 加载/odm/etc/audio_policy_configuration.xml                                     *     /vendor/etc/audio_policy_configuration.xml                                     *     /system/etc/audio_policy_configuration.xml                                     * 否则加载                                     *     /system/etc/audio_policy.conf                                     *     /vendor/etc/audio_policy.conf                                     */                                    AudioPolicyManager::loadConfig()                                        deserializeAudioPolicyXmlConfig()                                    // FIXME: Do a lot of things                                    AudioPolicyManager::initialize()                        new AudioPolicyEffects()                        new UIDPolicy(this)                        UIDPolicy::registerSelf()    // Oboe Service    AAudioService::instantiate()    SoundTriggerHwService::instantiate()
3.2 audioflinger

audioflinger实现了名为”media.audio_flinger”的binder本地端,而远程端由libaudioclIEnt的Iaudioflinger实现。

// 接口定义frameworks/av/include/media/Iaudioflinger.h // 实现audioflinger本地端libaudioflinger <==> frameworks/av/services/audioflinger/* // 实现audioflinger远程端libaudioclIEnt  <==> frameworks/av/media/libaudioclIEnt/*

audioflinger主要提供了如下接口

在AudioFliger中,将DeviceHalinterface抽象为AudioHwDevice(音频设备)和AudioStreamOut(音频输出流)

3.3 AudioPolicyService

AudioPolicyService实现了名为”media.audio_policy”的binder本地端,而远程端由libaudioclIEnt的IAudioPolicyService实现。

// 接口定义frameworks/av/include/media/IAudioPolicyService.h// 实现AudioPolicyService本地端libaudiopolicyservice <==> frameworks/av/services/audiopolicy/* // 实现AudioPolicyService远程端libaudioclIEnt        <==> frameworks/av/media/libaudioclIEnt/*

AudioPolicyService主要提供了如下接口

3.4 libaudioclIEnt

libaudioclIEnt实现了audioflinger和AudioPolicyService的远程端,并实现了如下接口供media JNI使用

// androID::media::*  <===> frameworks/av/media/libaudioclIEnt/// JNI                <===> frameworks/base/core/jni-----------------------------------------------------| androID::media::* | JNI                           |-----------------------------------------------------| AudioSystem.cpp   | androID_media_AudioSystem.cpp || AudioRecord.cpp   | androID_media_AudioRecord.cpp || AudioTrack.cpp    | androID_media_AudioTrack.cpp  |-----------------------------------------------------
3.5 AAudio

AAudio是在AndroID O版本中引入的全新AndroID C API。此API专为需要低延迟的高性能音频应用而设计。应用通过读取数据并将数据写入流来与AAudio进行通信。

// 接口定义frameworks/av/media/libaaudio/include/aaudio/AAudio.h// 实现AAudio服务libaaudioservice  <==> frameworks/av/services/oboeservice/*// 实现AAudio客户端libaaudio         <==> frameworks/av/media/libaaudio/*
4. Audio HAL

Audio HAL架构比较复杂,混合了HIDL和Legacy HAL,目前已经有一套成熟的框架
可参考<Android O Treble架构下Hal进程启动及HIDL服务注册过程>

对厂商来说,实现以so库的方式音频接口,并在音频政策配置文件(audio_policy_configuration.xml)进行配置,系统就会自动加载对应音频设备

4.1 音频接口

HAL接口定义在harDWare/libharDWare/include/harDWare/audio.h文件中

- audio_hw_device:  音频设备- audio_stream_out: 输出流- audio_stream_in:  输入流- audio_stream:     音频流

下面是当前已经实现或可参考的音频设备

默认主设备:       harDWare/libharDWare/modules/audio车载主设备:       device/generic/car/emulator/audio/driverUSB设备:          harDWare/libharDWare/modules/usbaudioRemoteSubmix设备: harDWare/libharDWare/modules/audio_remote_submix蓝牙A2DP设备:     system/bt/audio_a2dp_hw
4.2 HAL接口

Audio HAL接口(以2.0为例)是对音频接口的进一步抽象

// 音频设备IDevice.hal  |- initCheck()  |- setMasterVolume(float): 设置除voice call外其他音频活动的音量  |- getMasterVolume():      获取主音量  |- setMicMute(bool):       设置麦克风静音状态  |- getMicMute():           获取麦克风静音状态  |- setMasterMute(bool):    设置静音状态  |- getMasterMute(bool):    获取静音状态  |- getinputBufferSize(AudioConfig): 获取音频输入缓冲区大小  |- openOutputStream(*):    创建和打开音频硬件输出流  |- openinputStream(*):     创建和打开音频硬件输入流  |- supportsAudioPatches(): 判断HAL是否支持AudioPatch  |- createAudioPatch(*):    为SRC和SINK创建AudioPatch  |- releaseAudioPatch(*):   释放一个AudioPatch  |- getAudioPort(*):        获取指定音频端口属性  |- setAudioPortConfig(*):  配置音频端口  |- getHwAvSync():          获取设备的硬件同步源  |- setScreenState(bool):   设置屏幕状态  |- getParameters(vec<string>): 获取厂商定义的参数值  |- setParameters(vec<ParameterValue>): 设置厂商定义的参数值// 音频代理IDevicesFactory.hal  |- openDevice(Device):     打开一个音频设备// 主音频设备IPrimaryDevice.hal  |- setMasterVolume(float): 设置voice call音量  |- setMode(AudioMode):     设置音频模式  |- getBtScoNrecEnabled():  获取蓝牙ECNR使能状态  |- setBtScoNrecEnabled():  设置蓝牙ECNR使能状态  |- getBtScoWIDebandEnabled():     获取蓝牙WIDeband使能状态  |- setBtScoWIDebandEnabled(bool): 设置蓝牙WIDeband使能状态  |- getTtyMode():           获取当前TTY模式  |- setTtyMode():           设置当前TTY模式  |- getHacEnabled():        获取HearingAID使能状态  |- setHacEnabled():        设置HearingAID使能状态// 音频流IStream.hal  |- getFrameSize():         获取帧大小  |- getFrameCount():        获取缓冲区帧数  |- getBufferSize():        获取流的缓冲区大小  |- getSampleRate():        获取采样率(Hz)  |- getSupportedSampleRates():  获取流支持的支持的采样率(Hz)  |- setSampleRate(uint32_t):    设置流的采样率  |- getChannelMask():       获取流的channel mask  |- getSupportedChannelMasks(): 获取流支持的channel mask  |- setChannelMask():       获取流的channel mask  |- getFormat():            获取流的音频格式  |- getSupportedFormats():  获取流支持的音频格式  |- setFormat():            设置流的音频格式  |- getAudioPropertIEs():   获取流参数  |- addEffect():            添加音效到流  |- removeEffect(uint64_t): 从流上停止某音效  |- standby(uint64_t):      让硬件输入输出进入standby模式  |- getDevice():            获取流连接的设备  |- setDevice():            连接设置到流  |- setConnectedState():    通知设备连接状态  |- setHwAvSync(AudioHwSync):   设置硬件同步源  |- getParameters(vec<string>): 获取厂商参数  |- setParameters(vec<ParameterValue>):  设置厂商参数  |- start():                开始流 *** 作(mmap模式)  |- stop():                 停止流 *** 作  |- createmmapBuffer():     获取audio mmap缓冲区信息  |- getMmapposition():      读取audio mmap缓冲区读写位置  |- close():                关闭和释放流// 音频输入流IStreamIn.hal  |- getAudioSource():       获取输入流的source描述  |- setGain():              设置音频驱动的输入增益  |- prepareForReading():    设置必需的传输层以从驱动接收音频缓冲区  |- getinputFramesLost():   获取丢失的输入帧的数量  |- getCaptureposition():   获取接收到的音频帧数与时钟时间。// 音频输出流IStreamOut.hal  |- getLatency():           获取硬件传输延迟(毫秒)  |- setVolume(float, float):    设置音量, 用于混音后  |- prepareForWriting():    设置必需的传输层将音频缓冲区传递给驱动  |- getRenderposition():    获取音频DSP写入DAC的音频帧数  |- getNextWriteTimestamp():    获取下一次写入音频驱动时间(微秒)  |- setCallback():          设置回调接口, 用于非阻塞模式  |- clearCallback():        清楚回调  |- supportsPauseAndResume():   HAL是否支持暂停和恢复流  |- pause():                暂停流  |- resume():               恢复流  |- supportsDrain():        ???  |- drain():                ???  |- flush():                刷新流  |- getPresentationposition():  获取音频帧数// 音频输入流回调IStreamOutCallback.hal  |- onWriteReady():         非阻塞写入已完成  |- onDrainReady():         Drain(?)完成  |- one rror():              出错
4.3 HAL服务

Audio HAL服务对HAL接口和音频接口进行了HIDL方式地封装

/* * Code:   harDWare/interfaces/audio/common/all-versions/default/service/service.cpp * Output: /vendor/bin/hw/androID.harDWare.audio@2.0-service */main()   // 连接至vndservicemanager   androID::Processstate::initWithDriver("/dev/vndbinder")    androID::Processstate::self()->startThreadPool()   registerPassthroughServiceImplementation<audio::V4_0::IDevicesFactory>()   registerPassthroughServiceImplementation<audio::V2_0::IDevicesFactory>()   registerPassthroughServiceImplementation<audio::effect::V4_0::IEffectsFactory>()   registerPassthroughServiceImplementation<audio::effect::V2_0::IEffectsFactory>()   registerPassthroughServiceImplementation<soundtrigger::V2_1::ISoundTriggerHw>()   registerPassthroughServiceImplementation<soundtrigger::V2_0::ISoundTriggerHw>()   registerPassthroughServiceImplementation<bluetooth::a2dp::V1_0::IBluetoothAudioOffload>()   androID::harDWare::joinRpcThreadpool()# cat /vendor/etc/init/androID.harDWare.audio@2.0-service.rcservice vendor.audio-hal-2-0 /vendor/bin/hw/androID.harDWare.audio@2.0-service    class hal    user audioserver    oneshot    interface androID.harDWare.audio@4.0::IDevicesFactory default    interface androID.harDWare.audio@2.0::IDevicesFactory default# /vendor/etc/vintf/manifest.xml<manifest version="1.0" type="device" target-level="3">...    <hal format="hIDl">        <name>androID.harDWare.audio</name>        <transport>hwbinder</transport>        <version>4.0</version>        <interface>            <name>IDevicesFactory</name>            <instance>default</instance>        </interface>    </hal>...</manifest>
4.4 libaudiohal

libaudiohal封装了audio hal的接口,以libaudiohal.so的形式供audioflinger使用,而libaudiohal又使用了libaudiohal@4.0和libaudiohal@2.0两个库,同时libaudiohal@4.0和libaudiohal@2.0又分别是audio hal接口的封装

libaudiohal最终提供的是DeviceHalinterface、DevicesFactoryHalinterface和EffectsFactoryHalinterface接口

# tree frameworks/av/media/libaudiohal.+--- 2.0|   +--- AndroID.bp   -- libaudiohal@2.0+--- 4.0|   +--- AndroID.bp   -- libaudiohal@4.0+--- AndroID.bp       -- libaudiohal/* * DevicesFactoryHalinterface提供了create和openDevice两个方法 */DevicesFactoryHalinterface::create()    /*     * 这里仅仅分析了V2_0版本, V4_0类似     * 提供了两种方式来访问audio harDWare     *   - HIDL:   即DevicesFactoryHalHIDl, 用于primary, usb和remote_submix     *   - Legacy: 即DevicesFactoryHalLocal, 用于a2dp     */    new DevicesFactoryHalHybrID()        new DevicesFactoryHalLocal()        new DevicesFactoryHalHIDl()            harDWare::audio::V2_0::IDevicesFactory::getService()DevicesFactoryHalinterface::openDevice(char *name, DeviceHalinterface *device)    DevicesFactoryHalHybrID::openDevice(name, device)        // 针对hearing_aID和a2dp设备        DevicesFactoryHalLocal::openDevice(name, device)            load_audio_interface(name, audio_hw_device_t **dev)            new DeviceHalLocal(dev)        // 针对其他设备, 包括primary, usb, remote_submix设备        DevicesFactoryHalHIDl::openDevice(name, device)            // 获取HIDL接口名            nameFromHal(name, IDevicesFactory::Device &)            IDevicesFactory::openDevice()                new DeviceHalHIDl(IDevice)/* 这里暂不做分析 */EffectsFactoryHalinterface::create()

参考:
<Android音频>

总结

以上是内存溢出为你收集整理的Android Audio介绍全部内容,希望文章能够帮你解决Android Audio介绍所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1107985.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-29
下一篇2022-05-29

发表评论

登录后才能评论

评论列表(0条)

    保存