当前位置: 首页 > article >正文

android音频概念解析

音频硬件接口(我们可以理解为ASOC的声卡)

官方代码里叫audio hardware interface

也称为module,定义在services/audiopolicy/config/audio_policy_configuration.xml:

分别有primary,a2dp,usb,r_submix(用于 音频数据回环);

配置文件中的每一个module都被描述为HwModule,保存在mHwModules中;

output(devcie+thread) 我们可以理解为ASOC的substream概念

可以理解成是软件的输出通道,类比文件IO系统里面的stream概念。常用的输出通道类型有:

prmary_out,low_latency,deep_buffer,compress_offload,mutil_channel等;

定义在services/audiopolicy/config/audio_policy_configuration.xml;

每个输出通道类型都可以路由(route)到speaker,蓝牙设备,HDMI接口等;

配置文件中的每一个output都被描述为OutputProfile,保存在module->mOutputProfiles中;
这是一种常见的代码设计 思想,将能力级和实体解耦!

SwAudioOutputDescriptor

Output的描述符,真正的output实体,以output为句柄,保存在AudioPolicyManager的mOutputs中;

可以通过flag,device,streamtype去获取;
注意和outputprofile之间的区别。

PlaybackThread(对output中的数据进行搬运工作)

回放线程。

output在创建同时,会创建一个与之一一对应的PlaybackThread,句柄为output,保存在AudioFlinger的mPlaybackThreads中;

PlaybackThread的类型与配置文件中output的flag有关。

PlaybackThread与output一一对应,一旦确定了output,也就确定了PlaybackThread;

stream与Strategy

流类型很多,需要为将他们分类,将具有相同行为的stream分成一组,它们用一个Strategy:

具有相同行为的Stream:播放的设备一样,device相同,播放优先级相同。

stream,strategy,device,output,flag以及playbackthread之间如何关联起来?

①解析配置文件时,音频系统会将所有支持的output打开并初始化(如果没有活跃的track对应的thread会standby,减少CPU loading):

-->打开output
-->根据flag创建playbackthread

-->以output为句柄保存playbackthread;

播放声音时:

-->每个audiotrack都由自己的流类型stream type

-->根据streamtype匹配对应的strategy

-->根据strategy确定播放的设备device

-->根据device,flag确定所有符合条件的outputs
-->根据format,flags从ouputs中选择最中意的output

-->根据output确定playbackthread

-->通过Iaudiotrack把声音数据传给这个thread(这里就可以用到audiotrack那片文章的知识了)

8.AudioPolicyService启动过程

①读取解析配置文件

②根据配置文件调用AudioFlinger的服务,打开output,创建线程;

AudioPolicyService启动

读取解析配置文件

根据配置文件调用AudioFlinger,打开output,创建线程

void AudioPolicyService::onFirstRef()
     //所有的服务代码都需要线程/进程实体作为自己的承载,不然无法和调用方异步
    // start tone playback thread
    mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
    // start audio commands thread
    mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
    // start output activity command thread
    mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
    /*mAudioPolicyClient 就是AudioFlinger的客户端
     */
	mAudioPolicyClient = new AudioPolicyClient(this);
	mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

createAudioPolicyManager(mAudioPolicyClient)主要就是构建AudioPolicyManager,在AudioPolicyManager里面解析配置文件。

AudioPolicyService启动过程(策略加载以及音频服务体系构建)

a. 对于配置文件里的每一个module项, new HwModule(name), 放入mHwModules数组;
对于module里的每一个output, new IOProfile, 放入module的mOutputProfiles;
对于module里的每一个input, new IOProfile, 放入module的mInputProfiles;
b. 根据module的name加载厂家提供的so文件 (通过AudioFlinger来加载)
c. 打开对应的output (通过AudioFlinger来open output)

output选择的优先级

output的选择由AudioTrack创建引起,最终会走到AudioPolicyManager::getOutputForDevice()中;

选择output的逻辑优先级是:

flags > Format > primary > outputs0。


http://www.kler.cn/a/597778.html

相关文章:

  • 2025年2月-3月后端go开发找工作感悟
  • YOLO11改进|全网首发|YOLO11中引入轻量级坐标注意力LCA
  • Aider的Repo Map功能
  • 【开源宝藏】30天学会CSS - DAY6 第六课 流光文字动画
  • Linux网络相关概念和重要知识(3)(TCP套接字编程、远程命令的实现)
  • gotool.top 在线实时跨平台文件互传
  • 怎么绑定一个计算属性或数据属性来控制元素的类名
  • 31天Python入门——第9天:再学函数
  • Android Compose 状态保存(rememberSaveable、LocalSavedStateRegistry)框架深入剖析(十六)
  • 钞票准备好了吗?鸿蒙电脑 5 月见
  • Spring AOP 核心概念与实践指南
  • 【React】使用Swiper报错`Swiper` needs at least one child
  • ripro 主题激活 问题写入授权Token失败,可能无文件写入权限
  • 网络安全之前端学习(css篇1)
  • Hutool中的相关类型转换
  • 什么是TCP,UDP,MQTT?
  • 二叉树的学习
  • Docker容器之网络
  • 数据结构——B树、B+树、哈夫曼树
  • 【QA】Qt中有哪些命令模式的运用?