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

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。

相关文章:

  • mybatisplus雪花算法id重复日记
  • PicFlow:一个图片处理与上传工作流工具(图床上传工具)
  • Debian12生产环境配置笔记
  • systemctl restart 和 systemctl reload 和 systemctl daemon-reload 对比 笔记250322
  • SOFABoot-10-聊一聊 sofatboot 的十个问题
  • QEMU 引导时分离内核和文件系统
  • Collectors.toList / list 转 list
  • Netty——BIO、NIO 与 Netty
  • 第十六章:Specialization and Overloading_《C++ Templates》notes
  • ‌App Store美学竞争:如何通过广告素材分析实现ASO弯道超车‌
  • 基于Spring Boot 的在线教育系统(源码+lw+部署文档+讲解),源码可白嫖!
  • PRODIGY: “不折腾人”的蛋白-蛋白/蛋白-小分子结合能计算工具
  • SEO长尾关键词精准布局
  • 为什么后端路由需要携带 /api 作为前缀?前端如何设置基础路径 /api?
  • 批量图片压缩工具,高效减小文件大小并保持质量
  • deepSeek-SSE流式推送数据
  • OAuth 2.0认证
  • UE4学习笔记 FPS游戏制作12 添加第二把枪,制作枪的父类,动态生成物体,切换武器
  • 使用外部事件检测接入 CDH 大数据管理平台告警
  • 能不能解释一下 ,什么是React 的错误边界?
  • 让党的理论“飞入寻常百姓家”,他如何做到有新意?
  • 中虎跳峡封闭仍有游客逆行打卡,景区:专人值守防意外
  • 国家能源局:鼓励各地探索深远海、沙戈荒等可再生能源制氢场景
  • 加拿大总理将赴美同特朗普会晤,重点谈贸易压力
  • 澎湃读报丨央媒头版头条集中刊发:大国应有的样子
  • 乌美签署矿产协议