安卓音效AudioEffect源码剖析2——音效库接口
1、库的导出符号表——audio_effect_library_t
audio_effect_library_t的定义在hardware/libhardware/include/hardware/audio_effect.h中。
这个结构体在Android4.3+时有发生变化,query_num_effects()和query_effect()被删除。
如果希望做库兼容性,需要检测EFFECT_LIBRARY_API_VERSION,当其为
#ifEFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION) > 2时query_num_effects()和query_effect()不复存在。
typedef struct audio_effect_library_s {// tag must be initialized to AUDIO_EFFECT_LIBRARY_TAGuint32_t tag;// Version of the effect library API : 0xMMMMmmmm MMMM: Major, mmmm: minoruint32_t version;// Name of this libraryconst char *name;// Author/owner/implementor of the libraryconst char *implementor;//// Function: query_num_effects//// Description: Returns the number of different effects exposed by the// library. Each effect must have a unique effect uuid (see// effect_descriptor_t). This function together with EffectQueryEffect()// is used to enumerate all effects present in the library.//// Input/Output:// pNumEffects: address where the number of effects should be returned.//// Output:// returned value: 0 successful operation.// -ENODEV library failed to initialize// -EINVAL invalid pNumEffects// *pNumEffects: updated with number of effects in library//int32_t (*query_num_effects)(uint32_t *pNumEffects);//// Function: query_effect//// Description: Returns the descriptor of the effect engine which index is// given as argument.// See effect_descriptor_t for details on effect descriptors.// This function together with EffectQueryNumberEffects() is used to enumerate all// effects present in the library. The enumeration sequence is:// EffectQueryNumberEffects(&num_effects);// for (i = 0; i < num_effects; i++)// EffectQueryEffect(i,...);//// Input/Output:// index: index of the effect// pDescriptor: address where to return the effect descriptor.//// Output:// returned value: 0 successful operation.// -ENODEV library failed to initialize// -EINVAL invalid pDescriptor or index// -ENOSYS effect list has changed since last execution of// EffectQueryNumberEffects()// -ENOENT no more effect available// *pDescriptor: updated with the effect descriptor.//int32_t (*query_effect)(uint32_t index,effect_descriptor_t *pDescriptor);//// Function: create_effect//// Description: Creates an effect engine of the specified implementation uuid and// returns an effect control interface on this engine. The function will allocate the// resources for an instance of the requested effect engine and return// a handle on the effect control interface.//// Input:// uuid: pointer to the effect uuid.// sessionId: audio session to which this effect instance will be attached. All effects// created with the same session ID are connected in series and process the same signal// stream. Knowing that two effects are part of the same effect chain can help the// library implement some kind of optimizations.// ioId: identifies the output or input stream this effect is directed to at audio HAL.// For future use especially with tunneled HW accelerated effects//// Input/Output:// pHandle: address where to return the effect interface handle.//// Output:// returned value: 0 successful operation.// -ENODEV library failed to initialize// -EINVAL invalid pEffectUuid or pHandle// -ENOENT no effect with this uuid found// *pHandle: updated with the effect interface handle.//int32_t (*create_effect)(const effect_uuid_t *uuid,int32_t sessionId,int32_t ioId,effect_handle_t *pHandle);//// Function: release_effect//// Description: Releases the effect engine whose handle is given as argument.// All resources allocated to this particular instance of the effect are// released.//// Input:// handle: handle on the effect interface to be released.//// Output:// returned value: 0 successful operation.// -ENODEV library failed to initialize// -EINVAL invalid interface handle//int32_t (*release_effect)(effect_handle_t handle);//// Function: get_descriptor//// Description: Returns the descriptor of the effect engine which implementation UUID is// given as argument.//// Input/Output:// uuid: pointer to the effect uuid.// pDescriptor: address where to return the effect descriptor.//// Output:// returned value: 0 successful operation.// -ENODEV library failed to initialize// -EINVAL invalid pDescriptor or uuid// *pDescriptor: updated with the effect descriptor.//int32_t (*get_descriptor)(const effect_uuid_t *uuid,effect_descriptor_t *pDescriptor);
} audio_effect_library_t;
示例:
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {tag : AUDIO_EFFECT_LIBRARY_TAG,version : EFFECT_LIBRARY_API_VERSION,name : "Downmix Library",implementor : "The Android Open Source Project",create_effect : DownmixLib_Create,release_effect : DownmixLib_Release,get_descriptor : DownmixLib_GetDescriptor,
};
此处定义了创建和销毁的方法,但是作为效果链,怎么可能连个process处理都没有,稍安勿躁。
2、接口定义——effect_handle_t
这里,process和command都出现了。
typedef struct effect_interface_s **effect_handle_t;
struct effect_interface_s {//// Function: process//// Description: Effect process function. Takes input samples as specified// (count and location) in input buffer descriptor and output processed// samples as specified in output buffer descriptor. If the buffer descriptor// is not specified the function must use either the buffer or the// buffer provider function installed by the EFFECT_CMD_SET_CONFIG command.// The effect framework will call the process() function after the EFFECT_CMD_ENABLE// command is received and until the EFFECT_CMD_DISABLE is received. When the engine// receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully// and when done indicate that it is OK to stop calling the process() function by// returning the -ENODATA status.//// NOTE: the process() function implementation should be "real-time safe" that is// it should not perform blocking calls: malloc/free, sleep, read/write/open/close,// pthread_cond_wait/pthread_mutex_lock...//// Input:// self: handle to the effect interface this function// is called on.// inBuffer: buffer descriptor indicating where to read samples to process.// If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command.//// outBuffer: buffer descriptor indicating where to write processed samples.// If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command.//// Output:// returned value: 0 successful operation// -ENODATA the engine has finished the disable phase and the framework// can stop calling process()// -EINVAL invalid interface handle or// invalid input/output buffer descriptionint32_t (*process)(effect_handle_t self,audio_buffer_t *inBuffer,audio_buffer_t *outBuffer);//// Function: command//// Description: Send a command and receive a response to/from effect engine.//// Input:// self: handle to the effect interface this function// is called on.// cmdCode: command code: the command can be a standardized command defined in// effect_command_e (see below) or a proprietary command.// cmdSize: size of command in bytes// pCmdData: pointer to command data// pReplyData: pointer to reply data//// Input/Output:// replySize: maximum size of reply data as input// actual size of reply data as output//// Output:// returned value: 0 successful operation// -EINVAL invalid interface handle or// invalid command/reply size or format according to command code// The return code should be restricted to indicate problems related to the this// API specification. Status related to the execution of a particular command should be// indicated as part of the reply field.//// *pReplyData updated with command response//int32_t (*command)(effect_handle_t self,uint32_t cmdCode,uint32_t cmdSize,void *pCmdData,uint32_t *replySize,void *pReplyData);//// Function: get_descriptor//// Description: Returns the effect descriptor//// Input:// self: handle to the effect interface this function// is called on.//// Input/Output:// pDescriptor: address where to return the effect descriptor.//// Output:// returned value: 0 successful operation.// -EINVAL invalid interface handle or invalid pDescriptor// *pDescriptor: updated with the effect descriptor.//int32_t (*get_descriptor)(effect_handle_t self,effect_descriptor_t *pDescriptor);//// Function: process_reverse//// Description: Process reverse stream function. This function is used to pass// a reference stream to the effect engine. If the engine does not need a reference// stream, this function pointer can be set to NULL.// This function would typically implemented by an Echo Canceler.//// Input:// self: handle to the effect interface this function// is called on.// inBuffer: buffer descriptor indicating where to read samples to process.// If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command.//// outBuffer: buffer descriptor indicating where to write processed samples.// If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command.// If the buffer and buffer provider in the configuration received by// EFFECT_CMD_SET_CONFIG_REVERSE are also NULL, do not return modified reverse// stream data//// Output:// returned value: 0 successful operation// -ENODATA the engine has finished the disable phase and the framework// can stop calling process_reverse()// -EINVAL invalid interface handle or// invalid input/output buffer descriptionint32_t (*process_reverse)(effect_handle_t self,audio_buffer_t *inBuffer,audio_buffer_t *outBuffer);};
3、定制方法
库导出符号:
__attribute__ ((visibility("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {tag : AUDIO_EFFECT_LIBRARY_TAG,version : EFFECT_LIBRARY_API_VERSION,name : "Downmix Library",implementor : "The Android Open Source Project",create_effect : DownmixLib_Create,release_effect : DownmixLib_Release,get_descriptor : DownmixLib_GetDescriptor,
};
库的接口:
const struct effect_interface_s gDownmixInterface = {Downmix_Process,Downmix_Command,Downmix_GetDescriptor,NULL /* no process_reverse function, no reference stream needed */
};
库的内部参数:
typedef struct XXX_module_s {const structeffect_interface_s *itfe;XXconfig;
} XXX_module_t;
gDownmixInterface的用途,在create_effect中创建XXX_module_t,并设置
module->itfe = &gDownmixInterface;
注意:必须把conststruct effect_interface_s *itfe;作为结构体的第一个元素!
安卓音效AudioEffect源码剖析2——音效库接口相关推荐
- ZStack源码剖析之核心库鉴赏——FlowChain
本文首发于泊浮目的专栏:https://segmentfault.com/blog... 前言 在ZStack(或者说产品化的IaaS软件)中的任务通常有很长的执行路径,错误可能发生在路径的任意一处. ...
- AudioEffect源码解析
音效AudioEffect 如下图,应用程序开发者使用android.media.audiofx.AudioEffect来控制音效,它的子类包括:BassBoost, Environmental ...
- 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用 1...
老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用 上一节我们描述了monkey的命令处理入口函数run是如何调用optionPro ...
- 老李推荐: 第8章4节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 1...
老李推荐: 第8章4节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-启动AndroidDebugBridge 上一节我们看到在启动AndroidDebugBri ...
- 老李推荐: 第3章2节《MonkeyRunner源码剖析》脚本编写示例: MonkeyDevice API使用示例 1...
老李推荐: 第3章2节<MonkeyRunner源码剖析>脚本编写示例: MonkeyDevice API使用示例 上一节我们学习了如何通过MonkeyRunner这个类的静态方法wait ...
- 老李推荐:第14章4节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-端口转发 1...
老李推荐:第14章4节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-端口转发 在初始化HierarchyViewer的实例过程中, ...
- JS魔法堂:mmDeferred源码剖析
一.前言 avalon.js的影响力愈发强劲,而作为子模块之一的mmDeferred必然成为异步调用模式学习之旅的又一站呢!本文将记录我对mmDeferred的认识,若有纰漏请各位指正,谢谢.项目请见 ...
- Kafka源码剖析 —— 网络I/O篇 —— 浅析KafkaSelector
为什么80%的码农都做不了架构师?>>> ##NioSelector和KafkaSelector有什么区别? 先说结论,KafkaSelector(org.apache.kaf ...
- Mongoose源码剖析:Introduction and Installation
引言 要剖析Mongoose的源码,首先你得知道它的一些基本情况和特性.并去使用它.本文就是介绍Mongoose是个什么东西?及如何安装和使用?这里假设你知道什么web服务器软件.web服务器使用什么 ...
- 老李推荐:第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例 1...
老李推荐:第3章3节<MonkeyRunner源码剖析>脚本编写示例: MonkeyImage API使用示例 在上一节的第一个"增加日记"的示例中,我们并没有看到日记 ...
最新文章
- 2021阿里技术人的成长路径!
- log4j2的xml的配置样例
- 【C 语言】文件操作 ( 读文本文件 | 文本加密解密 | fgets 函数 | fputs 函数 )
- java.lang包怎么用_java.lang.io包的使用
- python 任务计划_使用Python添加计划任务
- 4.4 IPv6(诞生原因、数据报格式、与IPv4的不同、地址表现形式、基本地址类型、IPv6与IPv4的过渡策略)
- Boost::context模块callcc的stack测试程序
- 习惯性朴实简单!一起学习MySQL常见单行函数,字符数学日期流程控制
- http报文和协议首部
- WCF客户端动态设置WCF服务器主机的地址的方法参考,可以连接多个相同WCF主机的方法...
- 解决Sqlite Developer过期的办法
- 下载和安装Visual C ++ 2008 Express Edition的说明
- 原生android字体,安卓原生字体
- [知乎] 开放世界游戏中的大地图背后有哪些实现技术?
- 报错 Tensorflow 2.0 Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
- Facebook广告有哪些有效策略呢?
- 唯库拼课课程大合集更新111门
- Python Gym ImportError cannot import name ‘rendering‘ from ‘gym.envs.classic_control‘
- android 打开微信客户端,Android中接入微信客户端心得
- 怎么用计算机计算性别的公式,测男女的计算公式测了下挺准的