摘要:Android提供了一套音效处理的库,包括有BassBoost重低音,Equalizer均衡器,Virtualizer虚拟器,PresetReverb预置混响,EnvirenmentReverb环境音混响,Visaulizer可视化,downmix,preprocess(AGC(增益) AEC(回声消除) NS(噪声抑制))等。本文介绍音效库是如何从底层获取数据和为上层提供处理好的数据。

  一、如何加载库和创建音效

  以上这些音效分别封装在libbundlewrapper.so,libreverbwrapper.so,libvisualizer.so,libdownmix.so,libpreprocess.so等五个库中,这些库是由system/etc/audio_effects.conf这个配置文件中声明。加载该文件的地方有两个,一个是libeffect.so的EffectsFactory类,另外一个是libaudioflinger.so中的AudioPolicyService类。类工厂EffectsFactory使用了两个链表分别保存了lib和每个效果的结构体。目前使用到音效的地方有AudioFlinger中输出的各种音效, AudioMixer中的downmix, AudioPolicyService中的输入时的预处理preprocess。

  当创建一个音效时,由上层传入UUID到EffectsFactory中链表保存的音效中查询获得。java层media.audiofx包提供了java层的接口,JNI层有两个接口文件:android_media_AudioEffect.cpp和Android_media_visualizer.cpp,本地层有AudioEffect.cpp和Visualizer.cpp,在构造AudioEffect的构造函数中,根据Effect的UUID调用AudioFlinger的createEffect函数,从而调用类工厂EffectsFactory的EffectQueryNumberEffects查询并创建Effect的对象。

图1-1 AudioFx包类图

  二、音效数据的来源

  音效数据的来源需要分析AudioFlinger中的数据流的流程。首先我们先看一下hardware/libhardware/include/hardware/audio_effect.h定义了effect_config_t, buffer_config_t,audio_buffer_s等结构体,在audio_buffer_s中定义了保存输入数据的指针,我接下来看一下这些指针是在何处赋值。

  struct audio_buffer_s {
    size_t frameCount; // number of frames in buffer
    union {
      void* raw; // raw pointer to start of buffer
      int32_t* s32; // pointer to signed 32 bit data at start of buffer
      int16_t* s16; // pointer to signed 16 bit data at start of buffer
      uint8_t* u8; // pointer to unsigned 8 bit data at start of buffer
    };
  };

  当创建音效时,在AudioFlinger首先调用的是CreateEffect函数,当创建了一个effect实例后,要调用CreateEffect_l函数创建一个EffectHandle用于操作effect实例,并且判断该track是否已存在effectchain,如果不存在则创建一个effectChain然后将effect加入,如已存在则直接加入,在创建effectchain的部分指定了chain的inbuffer和outbuffer;将effect加入到effectchain的过程就是设置每个effect数据来源的地方,根据effect自己的flag属性确定它在chain中的位置。addEffect_l中调用了setInBuffer和setOutBuffer指定了数据源。

  三、硬件音效的实现

  目前的音频芯片很多都提供了部分硬件音效(如硬件EQ),其效果和效率是软件实现所不能够比的。根据硬件提供的控制节点,由mixer control将相应的值设置到声卡生效。

  四、总结

  本文通过跟踪一个音效创建分析音效的创建过程和音效的数据来源。

转载于:https://www.cnblogs.com/cerberspace/archive/2012/10/08/2707208.html

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. 一句话锁定MySQL数据占用元凶
  3. Android(安卓)Material Design之CardView(卡片式布局)
  4. 安卓向SD卡存储数据时java.io.FileNotFoundException:(Permissio
  5. Android(安卓)external.db和internal.db数据库
  6. Android:保存图片到Sqlite数据库
  7. 关于Android(安卓)6.0及以上版本用PendingIntent传送数据丢失问
  8. Andorid入门--HTTP数据传输和WebView的使用
  9. 【Android(安卓)Developers Training】 23. 序言:保存数据

随机推荐

  1. 玩转BeagleBoard xM——通过Repo下载Andr
  2. Android JNI编程内存问题定位方法
  3. ubuntu 64位 无法安装android SDK解决办
  4. Android仿人人客户端(v5.7.1)——欢迎和导
  5. android phone电话调用流程
  6. android 将时长毫秒转化为分钟和秒
  7. android binder机制之二 Service Manager
  8. [Android基础]四大组件之ContentProvider
  9. Android中onConfigurationChanged监视系
  10. Android Sqlite数据库跨版本升级 保存之