官方QQ群收藏本站

百问linux嵌入式论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 233|回复: 5

关于audio 的通道切换怎么设定device

[复制链接]

1

主题

4

帖子

37

积分

新手上路

Rank: 1

积分
37
发表于 2019-5-8 10:30:25 | 显示全部楼层 |阅读模式
1.关于audio 的通道切换怎么设定device
2.在创建audiotrack 的时候会先获取device 然后去选取output ,这个device 是怎么设置到底层的
回复

使用道具 举报

1

主题

4

帖子

37

积分

新手上路

Rank: 1

积分
37
 楼主| 发表于 2019-5-9 09:57:26 | 显示全部楼层
不懂请韦老师回复下,别不懂就卡在这里呀
回复 支持 反对

使用道具 举报

0

主题

73

帖子

271

积分

版主

Rank: 7Rank: 7Rank: 7

积分
271
发表于 2019-5-9 10:38:10 | 显示全部楼层
lailai001 发表于 2019-5-9 09:57
不懂请韦老师回复下,别不懂就卡在这里呀

虽然你的问题只有2个,但是已经覆盖了音频系统中大部分的内容。
我用了很多章节的视频来讲解音频系统,如果要详细回答你的这2个问题,估计可以写成一本书。
我先概括性地解答:

1.在创建audiotrack 的时候会先获取device 然后去选取output ,这个device 是怎么设置到底层的
答:
1.1
安卓系统中有一个配置文件:/system/etc/audio_policy.conf
里面一个module对应一个so文件,通常也就对应一个硬件声卡;
module里描述了这个声卡能支持哪些output,一个output能支持哪些device。
注意,一个声卡可以支持耳机、喇叭,即它有2个device: headphone, headset,
在驱动程序层面,这2个device都使用同一个驱动、同一个设备节点,只是需要通过不同的ioctl来使能。
通常来说,一个声卡有一个output, 在我们这个例子里,这个声卡有1个output, 2个device


1.2
安卓音频系统启动时,会根据配置文件去加载so文件,在so文件里会去打开设备节点;


这是在APP创建audiotrack之前就已经做好。




2. 关于audio 的通道切换怎么设定device
答:首先,写应用程序的人不应该去管什么device,它只设置自己产生的音频数据的类型,即stream
app要播放声音, 要指定声音类型: stream type
有那么多的类型, 来来来, 先看它属于哪一类(策略): strategy
根据strategy确定要用什么设备播放: device, 喇叭、耳机还是蓝牙?
根据device确定output, 进而知道对应的playbackthread,
把声音数据传给这个thread



即: stream -> strategy -> device (从配置文件里知道device对应哪个output、哪个so)  -> playbackthread


我担心,我写了这么一大堆,你可能也不好理解其中的概念。
我录制音频系统视频时,也是花了很多时间来理解这些概念。
所以我还是建议你从头看一下视频,看完之后你的问题自然就解决了。
想用1、2句话来回答,我做不到


我是韦东山
韦东山视频开发板购买店铺https://100ask.taobao.com/
微信公众平台:baiwenkeji
回复 支持 反对

使用道具 举报

1

主题

4

帖子

37

积分

新手上路

Rank: 1

积分
37
 楼主| 发表于 2019-5-9 10:53:12 | 显示全部楼层
本帖最后由 lailai001 于 2019-5-9 10:54 编辑

韦老师,你好!
           android audio 我也是根据你的视频学习,才进入这个行业,你的视频我也在反反复复的看,
我主要是2个问题:
1.在正常播放时是选定device然后去选择output ,因为你也没分析start函数,我想知道的是这一步开始
是怎么走的 ,是怎么一步步进入hal 层设定的

2.在切换通道时是
audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
setOutputDevice(desc, newDevice, force, 0);
这里你在视频只是简单的提下(有说在hal 层去深入,但是你hal 层后面就没提了),并没涉及深入,我是想请你从这里去分析怎么进入hal
回复 支持 反对

使用道具 举报

0

主题

73

帖子

271

积分

版主

Rank: 7Rank: 7Rank: 7

积分
271
发表于 2019-5-9 12:06:18 | 显示全部楼层
lailai001 发表于 2019-5-9 10:53
韦老师,你好!
           android audio 我也是根据你的视频学习,才进入这个行业,你的视频我也在反反 ...

HAL本身并不复杂,而是HAL之上的东西太复杂了,又涉及更多新的概念。

比如对于你的第2个问题:setOutputDevice 怎么一路进入HAL,


AudioPolicyManager.cpp:  setOutputDevice ,看源码注释可以知道它要做2件事情:
// do the routing
// update stream volumes according to new device


这很容易理解,先切换路由,即切换声音通道;再设计新设备的音量。


1. 切换路由:
mpClientInterface->createAudioPatch   ->
    android_media_AudioSystem.cpp  :  android_media_AudioSystem_createAudioPatch
            AudioSystem.cpp : createAudioPatch
               ......  最终可以找到 PatchPanel.cpp : AudioFlinger::PatchPanel::createAudioPatch
                         这个函数里有注释:
1.1 if (patch->sinks[0].ext.device.hw_module != srcModule)   // 使用不同的so文件,即从这个声卡切换到另一个声卡:
           audioflinger->openOutput_l  // 打开新的output
1.2 同一个声卡上,有些声卡有多个output:
1.2.1  if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0)
                  hwDevice->create_audio_patch   // 我们的HAL版本低于3.0,没有设计这个函数
1.2.2  
AudioParameter param = AudioParameter     
status = thread->setParameters(param.toString());   
                                        sendSetParameterConfigEvent_l


这是我们要分析的,这里又引入了新概念:参数设置,
在playbackthread的threadloop里,会调用processConfigEvents_l来处理这些参数,
又得往下分析,
切换路径时,执行到:AudioFlinger::PlaybackThread::createAudioPatch_l,
你可以看看 threads.cpp,它默认的代码是调用hwDevice->create_audio_patch,这需要API版本高于3.0,需要你提供这个函数:
  1. status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_patch *patch,
  2.                                                           audio_patch_handle_t *handle)
  3. {
  4.     status_t status = NO_ERROR;
  5.     if (mOutput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
  6.         // store new device and send to effects
  7.         audio_devices_t type = AUDIO_DEVICE_NONE;
  8.         for (unsigned int i = 0; i < patch->num_sinks; i++) {
  9.             type |= patch->sinks[i].ext.device.type;
  10.         }
  11.         mOutDevice = type;
  12.         for (size_t i = 0; i < mEffectChains.size(); i++) {
  13.             mEffectChains[i]->setDevice_l(mOutDevice);
  14.         }

  15.         audio_hw_device_t *hwDevice = mOutput->audioHwDev->hwDevice();
  16.         status = hwDevice->create_audio_patch(hwDevice,
  17.                                                patch->num_sources,
  18.                                                patch->sources,
  19.                                                patch->num_sinks,
  20.                                                patch->sinks,
  21.                                                handle);
  22.     } else {
  23.         ALOG_ASSERT(false, "createAudioPatch_l() called on a pre 3.0 HAL");
  24.     }
  25.     return status;
  26. }
复制代码


所以,在我们的android 5.0上,
要切换设备时,
1.新、旧设备如果位于不同的硬件上,那么最终会这样操作:
audioflinger->openOutput_l  // 打开新的output


2.新、旧设备位于相同的硬件上,通常是去设置音量即可(至于音量设计怎么到达HAL,这又是另一套分析过程了);
如果有特殊的硬件要设置,可以提供这个函数:
hwDevice->create_audio_patch(




音量等参数设置,涉及AudioMixer,你可以去看看。
很抱歉,我最终还是没能回答你的问题,因为音频相关的东西涉及的内容太多了,我无法分析完,
只能是引你们入门





     

我是韦东山
韦东山视频开发板购买店铺https://100ask.taobao.com/
微信公众平台:baiwenkeji
回复 支持 反对

使用道具 举报

1

主题

4

帖子

37

积分

新手上路

Rank: 1

积分
37
 楼主| 发表于 2019-5-13 16:16:04 | 显示全部楼层
OK 谢谢 后面的内容我自己分析下,对了 有个东西不太明白 关于output ,为什么一个output 不对应一个设备节点,如果不是这样 根据config 有好多output,他们都会建立自己的线程,也就是说有可能有多个output 会想访问同一个设备节点,但是这是不允许的。
回复 支持 反对

使用道具 举报

技术支持
在线咨询
咨询热线
0755-86200561
微信扫一扫
获取更多资讯!

Archiver|小黑屋|百问linux嵌入式论坛     

GMT+8, 2019-8-20 01:20 , Processed in 0.025791 second(s), 8 queries , File On.

Powered by Discuz! X3.3 Licensed

© 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

快速回复 返回顶部 返回列表