zoukankan      html  css  js  c++  java
  • Android音频(5)——框架中的概念和涉及的文件

    一、涉及的概念


    1. 概念output
    (1) 一个output对应一个或多个设备节点,比如/dev/snd/pcmC0D0p。为了避免麻烦,一个设备节点只由一个Thread(线程)操作。
    (2) 一个putput是多个device的组合(比如声卡上有喇叭(dev1)和耳机(dev2)),这些device(喇叭、耳机)属于同一个硬件上不同的端口。这些device需支持同样的参数,如采样率和通道。
    (3) 一个output对一个Thread,
    (4) 一个output对应一个或多个track(音轨),播放时来自多个App.
    (5) 一个track对应一个AudioTrack


    2. 使用Hardware Module(也称为module)来操作硬件
    Hardware Module的名字是什么?这决定加载哪些动态库。Hardware Module支持哪些output?output支持哪些device,参数是什么?
    以上这些在配置文件 /system/etc/audio_policy.conf 中指定


    3. 概念
    module: 硬件操作库,用于操作硬件
    output: 一组有相同参数的来自同一硬件的device.
    device: 喇叭,耳机等
    这些也与配置文件 /system/etc/audio_policy.conf 有关。

    4. profile和output的区别
    profile: 配置,用来描述output,比如可以支持哪些设备,和参数,比如采样率,通道等信息。
    output: 用于描述现在实际上可以支持哪些设备。
    比如一个具有喇叭和耳机孔的声卡的profile为可以支持喇叭和耳机,但是output是接上耳机时才支持耳机。


    5. App在播放音乐的时候有那么多的路径(比如播放到喇叭,耳机,蓝牙...),App怎么选择?
    答:App不管这些,这是由音频系统决定的。当App要显示指定类型的声音时,它只需要使用宏表明stream type(声音类型)即可。
    Java API和Native API使用的是不同的宏来指明stream type,但是它们是一一对应的,比如表示电话语音,Java中是STREAM_VOICE_CALL,Native中是AUDIO_STREAM_VOICE_CALL.
    这些宏在system/core/include/system/audio.h中定义。
    其中宏 AUDIO_STREAM_ENFORCED_AUDIBLE 表示强制发出声音,App不能mute它,必须发出来。比如有些国家要求拍照必须要有声音,以防止偷拍。

    6. 既然有多种stream type,不方便管理,于是对他们分了组,组使用strategy表示,具有相同行为的stream被放
    在同一个组中。这里的相同行为表示播放的device相同。
    分组信息可以参考hardware/libhardware_legacy/audio/AudioPolicyManagerBase.cpp中的getStrategy()

    AudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy(
            AudioSystem::stream_type stream) {
        // stream to strategy mapping
        switch (stream) {
        case AudioSystem::VOICE_CALL:
        case AudioSystem::BLUETOOTH_SCO:
            return STRATEGY_PHONE;
        case AudioSystem::RING:
        case AudioSystem::ALARM:
            return STRATEGY_SONIFICATION;
        case AudioSystem::NOTIFICATION:
            return STRATEGY_SONIFICATION_RESPECTFUL;
        case AudioSystem::DTMF:
            return STRATEGY_DTMF;
        default:
            ALOGE("unknown stream type");
        case AudioSystem::SYSTEM:
            // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
            // while key clicks are played produces a poor result
        case AudioSystem::TTS:
        case AudioSystem::MUSIC:
            return STRATEGY_MEDIA;
        case AudioSystem::ENFORCED_AUDIBLE:
            return STRATEGY_ENFORCED_AUDIBLE;
        }
    }
    View Code

    7. out flag
    每个output对应一个playbackthread,众多App都会把其数据丢给这个playbackthread,playbackthread就会把这些众多来源的
    声音混合在一起,然后再输出出去。
    有些特定的App会指定out flag为AUDIO_OUTPUT_FLAG_DIRECT,要求output不要混音,直接输出。比如输出到HDMI的声音数据可以指定这个flag。


    8. 总结:
    (1) Android系统里使用hardware module来访问硬件,比如声卡。声卡上有喇叭、耳机等等称为device。为了便于管理,把一个设备上具有相同参数的一组device称为output一个module能支持哪些output,一个output能支持哪些device,使用配置文件 /system/etc/audio_policy.conf 来描述。


    (2) app要播放出声音,需要指定声音的类型,也就是stream type,有那么多类型,系统会先看它属于哪一类strategy(策略),根据strategy确定要用什么device(设备)播放
    ,如喇叭,耳机还是蓝牙。根据device确定output,由于一个output对应一个thread,进而知道对应的playbackthread, 然后把声音传给这个thread。

    (3) 一个stream如何最终选择到一个device,这些stream如何互相影响(一个高优先级的声音会使其它声音静音)等等,统称为policy(政策)。主要不要搞混淆了,虽然中英文翻译policy是政策,strategy是策略,但是以后说Android音频的策略时,指的是pilicy。说strategy时,它指的是一组stream type.

    二、所涉及文件如下

    (1) main_mediaserver
    //在这个文件中启动AudioFlinger服务和AudioPolicyService服务
    frameworks/av/media/mediaserver/main_mediaserver.cpp

    (2) AudioFlinger
    //实现AudioFlinger Service端的Binder通信接口,onTransact(),对外提供接口如openOutput,openInput
    AudioFlinger.cpp (frameworks/av/services/audioflinger/AudioFlinger.cpp)

    //对每一个device都对应一个thread,这个thread就在这里面实现
    Threads.cpp (frameworks/av/services/audioflinger/Threads.cpp)

    //AudioFlinger中有个mTracks,用于存储应用程序发来的数据
    Tracks.cpp (frameworks/av/services/audioflinger/Tracks.cpp)

    //提供出来的硬件抽象层接口,厂商的HAL代码必须提供出这一套接口出来给上层使用
    audio_hw_hal.cpp (hardware/libhardware_legacy/audio/Audio_hw_hal.cpp)

    //这是由厂商提供的HAL文件
    AudioHardware.cpp (device/friendly-arm/common/libaudio/AudioHardware.cpp)

    //tinyalsa文件库中使用到的文件
    Mixer.c (external/)
    Pcm.c (external/)

    (3) AudioPolicyService

    //定义AudioPolicyService类内部使用到的函数和类
    AudioPolicyService.cpp (frameworks/av/services/audiopolicy/AudioPolicyService.cpp)

    //封装成对AudioFlinger的使用,也即是提供binder client接口。它是AudioFlinger的client
    AudioPolicyClientImpl.cpp (frameworks/av/services/audiopolicy/AudioPolicyClientImpl.cpp)

    //实现服务,实现各种服务接口函数,和binder的onTransact()
    AudioPolicyInterfaceImpl.cpp(frameworks/av/services/audiopolicy/AudioPolicyInterfaceImpl.cpp)

    //厂商也可以参与实现策略,这个文件制定了厂商需要遵循的规范,厂商需要继承AudioPolicyManagerBase类,重写其成员方法。
    AudioPolicyManagerBase.cpp (hardware/libhardware_legacy/audio/AudioPolicyManagerBase.cpp)

    //旧方法:AudioPolicyManager是厂商提供的策源管理文件,它必须派生自AudioPolicyManagerBase
    AudioPolicyManager.cpp (device/friendly-arm/common/libaudio/AudioPolicyManager.cpp)
    AudioPolicyManager.h (device/friendly-arm/common/libaudio/AudioPolicyManager.h)

    //旧方法基本上不使用了,这是新方法,系统已经实现了,厂家不需要参与策略的制定了。上面3个文件被以下文件替代
    AudioPolicyManager.cpp (frameworks/av/services/audiopolicy/AudioPolicyManager.cpp)

    (4) 应用程序APP所用文件:

    //C++实现的App并不直接使用AudioFlinger的接口,而是使用AudioTrack.cpp中实现的接口,它里面的接口
    //会通过binder与AudioFlinger服务通信
    AudioTrack.cpp (frameworks/av/media/libmedia/AudioTrack.cpp)
    AudioSystem.cpp (frameworks/av/media/libmedia/AudioSystem.cpp)

    //Java实现的App使用AudioTrack.java中实现的接口,通过android_media_AudioTrack.cpp中实现的JNI函数
    //调用到AudioTrack.cpp中实现接口。
    AudioTrack.java (frameworks/base/media/java/android/media/AudioTrack.java)
    android_media_AudioTrack.cpp (frameworks/base/core/jni/android_media_AudioTrack.cpp)

    优秀博客:

    Android系统中音频的输入输出设备

    Android系统Audio框架介绍

    Android 音频系统:从 AudioTrack 到 AudioFlinger

  • 相关阅读:
    FineReport---数据集
    FineReport----单元格元素(数据列、公式、斜线)
    FineReport---样式
    SQL-修改: 将日期修改为空NULL、修改为空的记录
    sql---字段类型转换,保留小数位数,取日期格式,sql获取当前时间,时间处理
    深入浅出Mqtt协议
    一文了解Redis
    RDBMS关系型数据库与HBase的对比
    Greedysky:C++ 建议用 nullptr 而不是 NULL
    Greedysky:C++11 新特性之强制类型转换static_cast
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10928125.html
Copyright © 2011-2022 走看看