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

济南建设设备安装有限责任公司官网seo建站优化

济南建设设备安装有限责任公司官网,seo建站优化,怎么做网站论坛,大网站有用香港空间的吗同一个音效,它绑定到不同的seesionId时,会被重新创建一个新的EffectModule对象。比如BassBoost低音增强音效,它被分别绑定到QQ音乐和酷狗音乐的sessionId时,就会创建两个不同的BassBoost对象。这样两个音效处理就会各不干扰。 前…

同一个音效,它绑定到不同的seesionId时,会被重新创建一个新的EffectModule对象。比如BassBoost低音增强音效,它被分别绑定到QQ音乐和酷狗音乐的sessionId时,就会创建两个不同的BassBoost对象。这样两个音效处理就会各不干扰。

前面讲了多个EffectChain之间的执行顺序,那么在EffectChain中的多个EffectModule,它们的执行顺序是什么呢?AudioFlinger是根据effect_descriptor_t结构体(音效算法描述类)中的flags来控制的。在你实现的音效算法指定的flags中可以指定下面flag的任意一种:

EFFECT_FLAG_INSERT_FIRST:表示将自己这个音效算法插入到EffectChain最前面。即:最先执行。如果有多个音效算法指定了这个flag,就按照创建EffectModule的时间先后排序,后创建的放在后面执行。

EFFECT_FLAG_INSERT_LAST:表示将这个音效算法插入到EffectChain的最后面执行。如果有多个音效算法声明此flag,后创建的EffectModule会插入到上次那个的前面。

EFFECT_FLAG_INSERT_ANY:表示将这个音效算法插入到INSERT_FIRST和INSERT_LAST之间。有多个时,按照加入的时间依次向后插入。

EFFECT_FLAG_INSERT_EXCLUSIVE:表示排它。意思是插入的EffectChain中,只能包含这一个音效算法。

以下就是EffectChain中多个EffectModule的执行顺序:

INSERT_FIRST1--》INSERT_FIRST2--》INSERT_ANY1--》INSERT_ANY2--》INSERT_LAST2--》INSERT_LAST1

当AudioFlinger中的PlaybackThread在执行时,会创建三个本地内存块:mMixerBuffer、mEffectBuffer、mSinkBuffer。

mMixerBuffer内存块中保存的是所有没有绑定任何音效算法的Track的音频数据。

mEffectBuffer内存块中保存的是所有经过音效算法处理后的Track的音频数据。

mSinkBuffer内存块中保存的是最终需要输出给AudioHAL进程中StreamOut的音频数据。

所有的Track数据,都会先传递给AudioMixer混音器进行多声道转换、采样精度调整、重采样后,才会传递给绑定的音效算法处理或传递给mMixerBuffer内存块。

当此次PlaybackThread播放时所有的Track都没有绑定音效算法,PlaybackThread会将mMixerBuffer中的数据直接拷贝到mSinkBuffer中。

当此次PlaybackTread播放时所有的Track都绑定了音效算法,mMixerBuffer内存块中就没有数据,就不会将其拷贝搬运到任何地方。

当此次PlaybackTread播放时即有绑定音效算法的Track,又有没有绑定的Track,PlaybackThread就会先将mMixerBuffer中的数据拷贝到mEffectBuffer中,再将mEffectBuffer的数据拷贝到mSinkBuffer中

注意这里如果有多个数据流向同一块buffer,则会进行混音。

Device音效的绑定过程(和sink关联)

Android中支持两种方式,将一个音效算法绑定到Device上处理。一种是动态创建一个AudioEffect对象,并给该对象指定的seesionId为AUDIO_SESSION_DEVICE。另一种是在audio_effects.xml文件的节点中申明,然后由AudioPolicyService解析后,通知AudioFlinger进行绑定。下面将说明一下通过audio_effects.xml配置文件的绑定方式。

AudioPolicyService在它的初始化函数onFirstRef()中,会创建AudioPolicyEffects对象,AudioPolicyEffects在其构造函数中就会进行audio_effects.xml文件的解析,然后通知AudioFlinger绑定音效。以下是代码调用流程

AudioPolicyService.cpp->onFirstRef()|->new AudioPolicyEffects()|->AudioPolicyEffects.cpp->loadAudioEffectXmlConfig()//mInputSources集合中保存的是<preprocess>节点中的配置。mOutputStreams集合中保存的是<postprocess>节点中的配置。mDeviceEffects集合中保存的是<deviceEffects>节点中的配置。|->EffectsConfig.cpp->parse()//libeffectsconfig|->AudioPolicyEffects.cpp->initDefaultDeviceEffects()

AudioPolicyEffects与EffectHAL一样,也是调用EffectsConfig.cpp->parse()来进行audio_effects.xml文件的解析,它会将节点中的配置保存到mDeviceEffects集合中,将节点中的配置保存到mInputSources集合,将节点中的配置保存到mOutputStreams集合中。

然后会调用initDefaultDeviceEffects()函数,通知AudioFlinger进行Device音效绑定。在该函数中,会为每个待绑定的音效算法,创建一个AudioEffect.cpp对象,并将sessionID设置为AUDIO_SESSION_DEVICE,将待绑定的DeviceType设置到AudioEffect对象中。然后调用AudioEffect->setEnabled(true)函数。这样做之后,AudioEffect对象在它的初始化时就会通知AudioFlinger绑定Device音效。以下是代码调用流程:

AudioPolicyEffects.cpp->initDefaultDeviceEffects()//绑定Device音效。为每个Device对应的所有Effect,都分别创建一个包名为android的客户端AudioEffect对象。并初始化它。

   |->AudioEffect.cpp->set(AUDIO_SESSION_DEVICE)|->AudioFlinger.cpp->createEffect()//Binder跨进程调用|->DeviceEffectManager.cpp->AudioFlinger::DeviceEffectManager::createEffect_l()|->new DeviceEffectProxy()//从mDeviceEffects列表中找不到此音效时,新创建一个。|->new EffectHandle()//mEffect引用的是DeviceEffectProxy对象|->Effects.cpp->AudioFlinger::DeviceEffectProxy::init()|->Effects.cpp->AudioFlinger::DeviceEffectProxy::onCreatePatch()|->Effects.cpp->AudioFlinger::DeviceEffectProxy::checkPort()//为当前Device绑定音效|->AudioEffect.cpp->setEnabled(true)       

从上面的代码流程可以看出,AudioFlinger通过自己的成员变量DeviceEffectManager创建了一个DeviceEffectProxy对象。而实现Device音效绑定的地方,是在DeviceEffectProxy::checkPort()函数中。这个函数为Device音效实现了两种绑定方式:

一种是让AudioHAL进程中的DeviceHAL直接处理音效数据。通过调用audio.h->audio_hw_device_t.add_device_effect(audio_port_handle_t device, effect_handle_t effect)接口实现。这种方式在音效算法处理过程中,就不会出现跨进程调用和共享内存创建的情况了。也就是说会由AudioHAL进程处理音效算法生成的数据,而不是AudioFlinger处理。AudioFlinger只负责控制音效算法的参数。

另一种方法是找到这个Device对应的PlaybackThread,由PlaybackThread去创建EffectModule对象,并插入到AUDIO_SESSION_DEVICE这个sessionId对应的EffectChain中,最终由PlaybackThread在传输音频数据时调用EffectChain->process_l()函数去处理音效算法生成的数据。也就是说由AudioServer进程负责处理音效数据。这种方式会出现跨进程调用和额外的共享内存创建。

DeviceHAL处理音效数据的方式

采用这种方式,加载的音效算法必须声明为前处理音效类型(EFFECT_FLAG_TYPE_PRE_PROC)或后处理音效类型(EFFECT_FLAG_TYPE_POST_PROC)。并且声明EFFECT_FLAG_HW_ACC_TUNNEL这个flag。它们都是通过在音效算法的实现代码中,设置effect_descriptor_t->flags来声明的。

在DeviceEffectProxy::checkPort()函数中,判断待绑定的音效算法如果包含EFFECT_FLAG_HW_ACC_TUNNEL flag,就会新创建一个EffectModule对象,将其保存到自己的DeviceEffectProxy::mHalEffect变量中。

下面我们看看AudioEffect.cpp->setEnabled(true)函数做了什么?

AudioPolicyEffects.cpp->initDefaultDeviceEffects()|->AudioEffect.cpp->setEnabled(true)|->Effects.cpp->AudioFlinger::EffectHandle::enable()//对应的是DeviceEffectProxy|->Effects.cpp->AudioFlinger::DeviceEffectProxy::setEnabled()|->Effects.cpp->AudioFlinger::EffectBase::setEnabled()//执行的是DeviceEffectProxy对象的方法|->Effects.cpp->AudioFlinger::EffectBase::setEnabled_l()//mState = STARTING,设置的是DeviceEffectProxy对象状态|->Effects.cpp->AudioFlinger::DeviceEffectProxy::ProxyCallback::onEffectEnable(sp<EffectBase>& effectBase)//传入的是DeviceEffectProxy对象,所以直接返回null|->Effects.cpp->AudioFlinger::EffectHandle::enable()//执行的DeviceEffectProxy的mEffectHandles集合中保存的EffectHandle对象,对应的是EffectModule对象|->Effects.cpp->AudioFlinger::EffectBase::setEnabled()//执行的是EffectModule对象的方法         |->Effects.cpp->AudioFlinger::EffectBase::setEnabled_l()//mState = STARTING,设置的是EffectModule对象状态|->Effects.cpp->AudioFlinger::DeviceEffectProxy::ProxyCallback::onEffectEnable(sp<EffectBase>& effectBase)传入的是EffectModule对象|->Effects.cpp->AudioFlinger::EffectModule::start()|->Effects.cpp->AudioFlinger::EffectModule::start_l()|->EffectHalHidl.cpp->command(EFFECT_CMD_ENABLE)//通知EffectHAL层enable|->Effects.cpp->AudioFlinger::EffectModule::addEffectToHal_l()//只有EFFECT_FLAG_TYPE_PRE_PROC或EFFECT_FLAG_TYPE_POST_PROC才执行下面的代码|->Effects.cpp->AudioFlinger::DeviceEffectProxy::ProxyCallback::addEffectToHal()|->Effects.cpp->AudioFlinger::DeviceEffectProxy::addEffectToHal() |->DeviceEffectManager.h->DeviceEffectManagerCallback::addEffectToHal()|->DeviceEffectManager.h->DeviceEffectManager::addEffectToHal()|->AudioFlinger.cpp->addEffectToHal()|->DeviceHalHidl.cpp->addDeviceEffect()|->Device.cpp->addDeviceEffect()//Binder跨进程调用|->EffectMap.cpp->EffectMap::getInstance().get(effectId)//源码在/hardware/interfaces/audio/common/all-versions/default/目录|->audio.h->audio_hw_device_t.add_device_effect()       

从上面这份代码调用流程可以看出,Effects.cpp文件中Effect和Callback之间的嵌套关系还是挺深的,最终通过层层调用,终于调用到了audio.h->audio_hw_device_t.add_device_effect(audio_port_handle_t device, effect_handle_t effect)接口。成功将此音效算法的effect_handle_t 句柄传递给DeviceHAL的audio_hw_device_t进行关联绑定。

http://www.dtcms.com/wzjs/98113.html

相关文章:

  • 泰安营销型手机网站建设网上哪里可以免费打广告
  • 广州企业网站磁力狗bt
  • 哪个网站可以做全网推广网络广告投放平台
  • 网络营销的市场背景手机游戏性能优化软件
  • 网站设计与开发的基本步骤包括哪些?sem优化公司
  • 设计一个网站的优势网络广告营销方案策划
  • 湖南服装网站建设微信公众号小程序怎么做
  • 用源码做网站步骤seo排名优化方式方法
  • 如何查楼盘剩余房源上海知名seo公司
  • 创建一个企业网站流程的步骤seo外链工具下载
  • 易思企业网站破解版优化关键词具体要怎么做
  • 如何推广自己的外贸网站怎么优化自己网站
  • 高级web程序设计—jsp网站开发 吴 课后习题答案天津seo托管
  • 帮一个公司做网站多少钱怎么做网络广告
  • 个人主页简介seo推广外包企业
  • 付费网站怎么做优化大师最新版本
  • iis网站301重定向白帽seo是什么
  • 哪个网站做网站好网站推广互联网推广
  • 门户网站建设情况简介aso关键词排名优化是什么
  • 优质网站建设在哪里安卓优化神器
  • 网站竞价推广都有哪些网络推广优化方案
  • 公司推广网站怎么做有创意的网络广告案例
  • 个人可以做下载类网站吗员工培训内容
  • 东莞高端做网站公司百度关键词网站排名优化软件
  • 阿里巴巴国际站网页设计教程上海今天最新发布会
  • 南乐网站建设费用网推平台
  • 佛山网站建设制作公司北京百度seo
  • 石家庄网站建设电话咨询网站推广的10种方法
  • 来个网站网站seo设计
  • 生物科技网站模板net的网站建设