Android系统源码分析/多媒体框架/音频子系统/常用结构体分析-audio.h
audio_stream_type_t
定义音频流类型,主要是手机系统各类典型的音频流做出属性上的区分,举个例子:电话和媒体2种类型的音频不管从输出的设备(耳机、功放、还是蓝牙)都是存在明显的不同。把这些明显不同的音频区分并加以定义,可以说对音频策略管理(AudioPolicyManager,在我后续的技术文章会具体jiang)和代码开发实现都存在很大必要性
/* Audio stream types */
typedef enum {/* These values must kept in sync with* frameworks/base/media/java/android/media/AudioSystem.java*/AUDIO_STREAM_DEFAULT = -1,AUDIO_STREAM_MIN = 0,AUDIO_STREAM_VOICE_CALL = 0,AUDIO_STREAM_SYSTEM = 1,AUDIO_STREAM_RING = 2,AUDIO_STREAM_MUSIC = 3,AUDIO_STREAM_ALARM = 4,AUDIO_STREAM_NOTIFICATION = 5,AUDIO_STREAM_BLUETOOTH_SCO = 6,AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user* and must be routed to speaker*/AUDIO_STREAM_DTMF = 8,AUDIO_STREAM_TTS = 9,AUDIO_STREAM_CNT,AUDIO_STREAM_MAX = AUDIO_STREAM_CNT - 1,
} audio_stream_type_t;
Stream Type | Description |
---|---|
AUDIO_STREAM_VOICE_CALL | 电话语音 |
AUDIO_STREAM_SYSTEM | 系统声音 |
AUDIO_STREAM_RING | 铃声声音,如来电铃声、闹钟铃声等 |
AUDIO_STREAM_MUSIC | 音乐声音 |
AUDIO_STREAM_ALARM | 警告音 |
AUDIO_STREAM_NOTIFICATION | 通知音 |
AUDIO_STREAM_DTMF | DTMF 音(拨号盘按键音) |
audio_content_type_t
内容类型定义了声音是什么,并指明内容的常规类别,如电影、语音或提示音/铃声。音频框架使用内容类型信息来选择性地配置音频处理后块。尽管提供内容类型是可选的,但只要内容类型已知,您就应该包含类型信息,例如针对电影流式传输服务使用 CONTENT_TYPE_MOVIE
,或针对音乐播放应用使用 CONTENT_TYPE_MUSIC
typedef enum {AUDIO_CONTENT_TYPE_UNKNOWN = 0,AUDIO_CONTENT_TYPE_SPEECH = 1,AUDIO_CONTENT_TYPE_MUSIC = 2,AUDIO_CONTENT_TYPE_MOVIE = 3,AUDIO_CONTENT_TYPE_SONIFICATION = 4,AUDIO_CONTENT_TYPE_CNT,AUDIO_CONTENT_TYPE_MAX = AUDIO_CONTENT_TYPE_CNT - 1,
} audio_content_type_t;
audio_source_t
这个枚举定义了各种音频输入设备,比如AUDIO_SOURCE_MIC麦克风 AUDIO_SOURCE_VOICE_CALL电话通话录音 AUDIO_SOURCE_CAMCORDER 摄像头音频录制 AUDIO_SOURCE_VOICE_COMMUNICATION 摄像头旁边的麦克风 AUDIO_SOURCE_VOICE_RECOGNITION语音识别 AUDIO_SOURCE_VOICE_UPLINK 电话通话上行声音 AUDIO_SOURCE_VOICE_DOWNLINK电话通话下行声音 AUDIO_SOURCE_REMOTE_SUBMIX 类似于同屏器设备,比如手机把手机的的画面投在电视机上,那么音频数据一定是通过WIFI传递给同屏器。(我司最近给移动开发的同屏器产品就是通过这个类型的音频输入设备实现音频 从手机到电视的传输)
typedef enum {AUDIO_SOURCE_DEFAULT = 0,AUDIO_SOURCE_MIC = 1,AUDIO_SOURCE_VOICE_UPLINK = 2,AUDIO_SOURCE_VOICE_DOWNLINK = 3,AUDIO_SOURCE_VOICE_CALL = 4,AUDIO_SOURCE_CAMCORDER = 5,AUDIO_SOURCE_VOICE_RECOGNITION = 6,AUDIO_SOURCE_VOICE_COMMUNICATION = 7,AUDIO_SOURCE_REMOTE_SUBMIX = 8, /* Source for the mix to be presented remotely. *//* An example of remote presentation is Wifi Display *//* where a dongle attached to a TV can be used to *//* play the mix captured by this audio source. */AUDIO_SOURCE_CNT,AUDIO_SOURCE_MAX = AUDIO_SOURCE_CNT - 1,AUDIO_SOURCE_HOTWORD = 1999, /* A low-priority, preemptible audio source forfor background software hotword detection.Same tuning as AUDIO_SOURCE_VOICE_RECOGNITION.Used only internally to the framework. Not exposedat the audio HAL. */
} audio_source_t;
audio_format_pcm_sub_fmt_t audio_format_mp3_sub_fmt_t audio_format_amr_sub_fmt_t audio_format_aac_sub_fmt_t
这几个枚举类型定义了pcm mp3 amr aac音频格式和各个格式 子类型。
audio_format_t
typedef enum {AUDIO_FORMAT_INVALID = 0xFFFFFFFFUL,AUDIO_FORMAT_DEFAULT = 0,AUDIO_FORMAT_PCM = 0x00000000UL, /* DO NOT CHANGE */AUDIO_FORMAT_MP3 = 0x01000000UL,AUDIO_FORMAT_AMR_NB = 0x02000000UL,AUDIO_FORMAT_AMR_WB = 0x03000000UL,AUDIO_FORMAT_AAC = 0x04000000UL,AUDIO_FORMAT_HE_AAC_V1 = 0x05000000UL, /* Deprecated, Use AUDIO_FORMAT_AAC_HE_V1*/AUDIO_FORMAT_HE_AAC_V2 = 0x06000000UL, /* Deprecated, Use AUDIO_FORMAT_AAC_HE_V2*/AUDIO_FORMAT_VORBIS = 0x07000000UL,AUDIO_FORMAT_OPUS = 0x08000000UL,AUDIO_FORMAT_AC3 = 0x09000000UL,AUDIO_FORMAT_E_AC3 = 0x0A000000UL,AUDIO_FORMAT_MAIN_MASK = 0xFF000000UL,AUDIO_FORMAT_SUB_MASK = 0x00FFFFFFUL,/* Aliases *//* note != AudioFormat.ENCODING_PCM_16BIT */AUDIO_FORMAT_PCM_16_BIT = (AUDIO_FORMAT_PCM |AUDIO_FORMAT_PCM_SUB_16_BIT),/* note != AudioFormat.ENCODING_PCM_8BIT */AUDIO_FORMAT_PCM_8_BIT = (AUDIO_FORMAT_PCM |AUDIO_FORMAT_PCM_SUB_8_BIT),AUDIO_FORMAT_PCM_32_BIT = (AUDIO_FORMAT_PCM |AUDIO_FORMAT_PCM_SUB_32_BIT),AUDIO_FORMAT_PCM_8_24_BIT = (AUDIO_FORMAT_PCM |AUDIO_FORMAT_PCM_SUB_8_24_BIT),AUDIO_FORMAT_PCM_FLOAT = (AUDIO_FORMAT_PCM |AUDIO_FORMAT_PCM_SUB_FLOAT),AUDIO_FORMAT_PCM_24_BIT_PACKED = (AUDIO_FORMAT_PCM |AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED),AUDIO_FORMAT_AAC_MAIN = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_MAIN),AUDIO_FORMAT_AAC_LC = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_LC),AUDIO_FORMAT_AAC_SSR = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_SSR),AUDIO_FORMAT_AAC_LTP = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_LTP),AUDIO_FORMAT_AAC_HE_V1 = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_HE_V1),AUDIO_FORMAT_AAC_SCALABLE = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_SCALABLE),AUDIO_FORMAT_AAC_ERLC = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_ERLC),AUDIO_FORMAT_AAC_LD = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_LD),AUDIO_FORMAT_AAC_HE_V2 = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_HE_V2),AUDIO_FORMAT_AAC_ELD = (AUDIO_FORMAT_AAC |AUDIO_FORMAT_AAC_SUB_ELD),
} audio_format_t;
定义了安卓手机系统用到的音频格式和子格式的定义。具体每个格式的含义不在这里具体展开,那是一个很大的课题。
关于PCM格式推荐一篇文章:https://blog.csdn.net/lifei092/article/details/80990813
关于MP3格式推荐一篇文章:https://www.cnblogs.com/ranson7zop/p/7655474.html
关于AAC格式推荐一篇文章:https://www.jianshu.com/p/30856dccd9cb
关于AC3格式推荐一篇文章:https://blog.csdn.net/u013291802/article/details/53283944
audio_output_flags_t
typedef enum {AUDIO_OUTPUT_FLAG_NONE = 0x0, // no attributesAUDIO_OUTPUT_FLAG_DIRECT = 0x1, // this output directly connects a track// to one output stream: no software mixerAUDIO_OUTPUT_FLAG_PRIMARY = 0x2, // this output is the primary output of// the device. It is unique and must be// present. It is opened by default and// receives routing, audio mode and volume// controls related to voice calls.AUDIO_OUTPUT_FLAG_FAST = 0x4, // output supports "fast tracks",// defined elsewhereAUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8, // use deep audio buffersAUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD = 0x10, // offload playback of compressed// streams to hardware codecAUDIO_OUTPUT_FLAG_NON_BLOCKING = 0x20, // use non-blocking writeAUDIO_OUTPUT_FLAG_HW_AV_SYNC = 0x40 // output uses a hardware A/V synchronization source
} audio_output_flags_t;
AUDIO_OUTPUT_FLAG | Description |
---|---|
AUDIO_OUTPUT_FLAG_DIRECT | 表示音频流直接输出到音频设备,不需要软件混音,一般用于 HDMI 设备声音输出 |
AUDIO_OUTPUT_FLAG_PRIMARY | 表示音频流需要输出到主输出设备,一般用于铃声类声音 |
AUDIO_OUTPUT_FLAG_FAST | 表示音频流需要快速输出到音频设备,一般用于按键音、游戏背景音等对时延要求高的场景 |
AUDIO_OUTPUT_FLAG_DEEP_BUFFER | 表示音频流输出可以接受较大的时延,一般用于音乐、视频播放等对时延要求不高的场景 |
AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | 表示音频流没有经过软件解码,需要输出到硬件解码器,由硬件解码器进行解码 |
audio_input_flags_t
针对输入音频源
AUDIO_INPUT_FLAG_NONE表示输入音频是常规音频输入,即咱们常见的摄像头或者麦克风采集的数据;AUDIO_INPUT_FLAG_FAST表述输入音频是延时要求高的音频输入源,如按键音游戏背景;AUDIO_INPUT_FLAG_HW_HOTWORD主要用于语音识别。可能要做的事情是:处理代码需要对数据识别并提取说话内容
typedef enum {AUDIO_INPUT_FLAG_NONE = 0x0, // no attributesAUDIO_INPUT_FLAG_FAST = 0x1, // prefer an input that supports "fast tracks"AUDIO_INPUT_FLAG_HW_HOTWORD = 0x2, // prefer an input that captures from hw hotword source
} audio_input_flags_t;
audio_offload_info_t
该结构体描述offload流的具体信息,所谓offload就是需要硬件解码的音频流。采样率、左右立体声声道、pcm子格式、流类型、比特率以及流是static模式(一次写入播放)还是stream模式(多次写入播放)
typedef struct {uint16_t version; // version of the info structureuint16_t size; // total size of the structure including version and sizeuint32_t sample_rate; // sample rate in Hzaudio_channel_mask_t channel_mask; // channel maskaudio_format_t format; // audio formataudio_stream_type_t stream_type; // stream typeuint32_t bit_rate; // bit rate in bits per secondint64_t duration_us; // duration in microseconds, -1 if unknownbool has_video; // true if stream is tied to a video streambool is_streaming; // true if streaming, false if local playback
} audio_offload_info_t;
audio_module_handle_t
定义为int类型,表示一个硬件模块,所谓硬件模块是usb downmix a2dp蓝牙 以及primary 四种之一。配置信息在audio_policy.conf描述
具体可以见另外一个文章:https://www.cnblogs.com/wulizhi/p/8179067.html
audio_port_role_t
描述一个port的规则:对于输入就是source ,对于输出就是sink
typedef enum {AUDIO_PORT_ROLE_NONE,AUDIO_PORT_ROLE_SOURCE,AUDIO_PORT_ROLE_SINK,
} audio_port_role_t;
audio_port_type_t
描述输出端口的三个类型:device就是直接向具体的设备进行输出(AUDIO_DEVICE_OUT_SPEAKER)、MIX类型就是向mixthread进行输出(需要做一些重编码、混音、音效处理、音量策略处理动作)、SESSION就是向另外一个audiotrack进行数据输出(举例:这样可以添加自定义音频数据处理挂钩)
typedef enum {AUDIO_PORT_TYPE_NONE,AUDIO_PORT_TYPE_DEVICE,AUDIO_PORT_TYPE_MIX,AUDIO_PORT_TYPE_SESSION,
} audio_port_type_t;
audio_port_config_device_ext
描述一个port输出设备:包含改设备对应的hw_module(所谓hw_module上面已经解释)、设备类型(AUDIO_DEVICE_OUT_SPEAKER)、设备地址
struct audio_port_config_device_ext {audio_module_handle_t hw_module; /* module the device is attached to */audio_devices_t type; /* device type (e.g AUDIO_DEVICE_OUT_SPEAKER) */char address[AUDIO_DEVICE_MAX_ADDRESS_LEN]; /* device address. "" if N/A */
};
audio_port_config_mix_ext
描述port如果输出对象是一个MIX Thread,那么该对象描述该输出配置信息:包含改设备对应的hw_module(所谓hw_module上面已经解释)、输出的IO对象(该io对象对应AudioFilger里面的一个PlaybackThread)、流类型和输入源类型
struct audio_port_config_mix_ext {audio_module_handle_t hw_module; /* module the stream is attached to */audio_io_handle_t handle; /* I/O handle of the input/output stream */union {//TODO: change use case for output streams: use strategy and mixer attributesaudio_stream_type_t stream;audio_source_t source;} usecase;
};
audio_port_config
我们需要解释什么是audioport,在解释之前我们先说下另外一个概念:audio patch。那么什么是audio patch?
我们举个例子:近期做了一个车载音频播放设备,该设备声音源来自汽车车载音响,然后通过usb设备传到手机,再通过手机的扬声器播放出来;为了达到这个目的,音频源数据从source 设备(车载音响usb接口)到目标设备(loud speaker)直接建立一个patch就可以了。 数据可以快速的输出,避免经过用户层中转。 提高了音频的实时性
在一个audio patch中,我们输入设备可以不只是一个(除了车载音响,还可以是手机自带的麦克风),输出设备也不只是一个(除了loud speaker,还可以是录制文件。这个场景怎么理解? 车载录音证据保留目的 )
那么既然一个patch内有多个输如输出,这里面一个输入就叫做一个端口,即audio_port。所以audio_port_config 就是描述port配置属性的
id是该config唯一id;
role指明该port是输入AUDIO_PORT_ROLE_SOURCE还是输出AUDIO_PORT_ROLE_SINK;
tye指明该porta是device mix 还是一个session;
config_mask是一个AUDIO_PORT_CONFIG_ALL AUDIO_PORT_CONFIG_GAIN AUDIO_PORT_CONFIG_FORMAT AUDIO_PORT_CONFIG_CHANNEL_MASK 四个值中的一个,这样可以指明下面字段channel format gain三个字段哪一个是有效的。下面是config_mask的定义
#define AUDIO_PORT_CONFIG_SAMPLE_RATE 0x1 |
sample_rate是该port的采样率
channel_mask:指明该port是左声道 右声道还是 立体声
format 指出音频数据的格式
gain 指出该port的增益属性
ext则是一个联合体,根据type是device mix session,该字段相应的是audio_port_config_device_ext audio_port_config_mix_ext audio_port_config_session_ext
/* audio port configuration structure used to specify a particular configuration of* an audio port */
struct audio_port_config {audio_port_handle_t id; /* port unique ID */audio_port_role_t role; /* sink or source */audio_port_type_t type; /* device, mix ... */unsigned int config_mask; /* e.g AUDIO_PORT_CONFIG_ALL */unsigned int sample_rate; /* sampling rate in Hz */audio_channel_mask_t channel_mask; /* channel mask if applicable */audio_format_t format; /* format if applicable */struct audio_gain_config gain; /* gain to apply if applicable */union {struct audio_port_config_device_ext device; /* device specific info */struct audio_port_config_mix_ext mix; /* mix specific info */struct audio_port_config_session_ext session; /* session specific info */} ext;
};
android系统音频子系统的其他代码分析,会逐步更新到我的博客。敬请关注
Android系统源码分析/多媒体框架/音频子系统/常用结构体分析-audio.h相关推荐
- Android系统源码目录及功能介绍
Android的移植按如下流程: 1.android linux 内核的普通驱动移植,让内核可以在目标平台上运行起来. 2.正确挂载文件系统,确保内核启动参数和 android 源代码 ...
- 大牛们是怎么阅读 Android 系统源码的?
转载自https://www.zhihu.com/question/19759722 作者:王宇龙 链接:https://www.zhihu.com/question/19759722/answer/ ...
- Android 系统的分区和文件系统(1)- Android 系统源码结构分析
声明 本文分析Android系统源码各目录存放文件用途. 其中参考了一些书籍内容,仅供学习使用. 本文采用 LinesgeOS cm-14.1(等同于AOSP Android 7.1.1) 1. 整体 ...
- Android系统源码
作者:王宇龙 链接:https://www.zhihu.com/question/19759722/answer/29213925 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
- android 系统源码介绍
一.系统目录 1.1 系统目录含义 1.2 系统jar作用 Android系统源码目录 system/framework 下各个jar包的用途 am.jar:终端下执行am命令时所需的java库.源码 ...
- android系统源码之 系统应用安装过程(下)
android系统源码之 系统应用安装过程(上) :http://blog.csdn.net/king1425/article/details/70135813 下图是PackageParser主要数 ...
- ubuntu-18.04.4 Android系统源码TP1A(Android 13)下载及编译
继上一篇博客介绍了VMware Workstation15 配置ubuntu-18.04.4,这篇主要介绍安装后环境搭建,Android源码的下载与编译.小编当前下载的是当前最新的代码,是主干分支代码 ...
- android系统源码7.1.2_r8下载,编译,运行到nexus5X上,修改源码并编译SDK进行测试
一,学习android系统源码下载,编译的作用 1,可以自己 DIY 自己的rom系统,从系统层面,宏观的加深理解 android系统 2,编译自己的 userdebug(原生root权限) rom, ...
- Android FrameWork学习(二)Android系统源码调试
点击打开链接 通过上一篇 Android FrameWork学习(一)Android 7.0系统源码下载\编译 我们了解了如何进行系统源码的下载和编译工作. 为了更进一步地学习跟研究 Android ...
最新文章
- 继续过中等难度.0309
- 基于 Docker 的 MySQL 导入导出数据
- nginx lua 安装spdy
- 【设计模式】java设计模式之 -- 策略模式
- 获取当前正在执行的方法的名称
- VHDL的数据对象(学习笔记1)
- 数制转换itoa atoi int转字符串 字符串转int string转int int转string
- Sharepoint项目周记一:关于开展MOSS项目的前期调查和需要解决的问题
- linux 查看emmc分区表_如何查看闪存类型?UFS与F2FS简易科普
- 今天买到了回家的火车票,有座儿,心情不错.
- 联合 5 位大佬送 210 本实体书,包邮到家!
- python老男孩scrapy视频刷课记录
- 随机点名和抽题软件(可支持ppt扩展模式使用)
- ASP.NET常用服务器控件
- 太乐地图下载器5.0.5(破解版)
- torch.nn.MaxPool1d各参数分析
- [linux小水滴]工具安装与使用
- 生命不息,折腾不止——新的起点
- 论文查重的步骤是什么?
- 关于新三板的股份锁定问题
热门文章
- slowfast代码实现和论文理解
- ec2 linux root,亚马逊EC2服务器centos7 如何开启root账号登陆
- EAUML日拱一卒-微信小程序实战:位置闹铃 (19)-发布微信小程序
- 以前seo和现在seo的区别和演变
- APICloud开发之新手上路!自定义Loader编译后安装包解析出错。
- can‘t convert from BSON type long to Date
- 私域营销突围,需要一点“无忌”精神
- 老李分享:什么是好战略
- Docker 快速入门(一文上手 Docker)
- 万米高空的太平洋上,我想跟老婆视个频