如何在项目中引入OpenSL ES
在android ndk相关目录下已经引入了opensles.so。
因此可以在 CMakeList.txt中加入 直接使用。
Objects 和 Interfaces
OpenSL ES 有两个必须理解的概念,就是 Object (对象)和 Interface(接口) :
- 对象是一组功能的抽象,每个对象都包含了许多的接口,由这些接口提供具体的功能。
- 每个 Object 对象都提供了一些最基础的操作,比如:Realize,Resume,GetState,Destroy 等等,如果希望使用该对象支持的功能函数,则通过其 GetInterface 函数拿到 接口,然后通过接口来访问具体功能。
在 “OpenSLES.h” 文件可以看到 OpenSL ES 定义的所有 Object 对象的 ID,通过这些Object ID 来创建对应的对象实例。
同样,“OpenSLES.h” 文件中还定义了所有的 Interface ID,通过 Interface ID 可以从对象中获取到对应的功能接口。
OpenSL ES 的状态机制
任何一个 OpenSL ES 的对象,创建成功后,都进入 SL_OBJECT_STATE_UNREALIZED 状态,这种状态下,系统不会为它分配任何资源。
调用Realize 后的对象, 会分配相关的资源,进入 SL_OBJECT_STATE_REALIZED 状态,这是一种“可用”的状态,只有在这种状态下,对象的各个功能才能正常地访问。
当一些系统事件发生后,比如出现错误或者 Audio 设备被其他应用抢占,OpenSL ES 对象会进入 SL_OBJECT_STATE_SUSPENDED 状态, 调用Resume()可以恢复到 SL_OBJECT_STATE_REALIZED 状态。
当调用对象的 Destroy 函数后,则会释放资源,回到 SL_OBJECT_STATE_UNREALIZED 状态。
Engine Object
OpenSL ES 里面最核心的对象就是:Engine Object(音频引擎对象),它主要提供如下功能:
- 提供引擎接口: SLEngineItf,该接口可以用来创建所有其他的 Object 对象
Engine Objec创建 &初始化
获取SLEngineItf接口,获取后 就可以使用 engineEngine 来创建 OpenSL ES 的其他对象了。
最后不用了就销毁
使用流程
- 1、获取引擎接口
- 2、创建输出混音器
- 3、创建播放器,并获取播放接口
- 4、获取缓冲队列接口并给缓冲队列注册回调函数
- 5、设置播放状态、手动调用回调函数
1、获取引擎接口
获取引擎接口至关重要,后面所有的对象都是通过引擎接口创建的。
OpenSLES接口的获取都是遵循这三步,先创建对象、再初始化对象、最后通过接口id从对象获取对应功能的接口。最后不用的时候可以调用对象的Destroy函数进行销毁。
2、创建输出混音器
3、创建播放器并获取播放接口:创建播放器还需要为播放器指定Data Source 和 Data Sink 。
- data source 代表着输入源的信息,即数据从哪儿来、输入的数据格式是怎样的。
- data sink 代表着输出的信息,即数据输出到哪儿、以什么样的方式输出。
data source和data sink的结构体如下:
对于pLocator来说,通常有下面这些常用值:
4、获取缓冲队列接口并给缓冲队列注册回调函数
5、设置播放状态、手动调用回调函数
当设置了播放器为播放状态,该音频播放器开始等待缓存取队列就绪。
回调函数如下:
第一次我们手动调用了回调函数,然后会通过Enqueue函数将数据入队,接着播放器会从缓冲队列中取出数据进行播放,每次缓冲队列数据播放完成都会调用回调函数,回调又接着往缓冲队列中放入数据。
最后在适当的时候释放所有资源: