Android音频开发(6):使用 OpenSL ES API(上)

qgpi7527 8年前
   <p> </p>    <p>前面几篇文章介绍了如何在 Java 层,利用 Android 提供的 AudioRecord 采集音频,利用 AudioTrack 播放音频,利用 MediaCodec 来编解码,这些 API 均是 Android 提供的 Java 层 API,无论是采集、播放还是编解码,这些 API 接口都需要将音频数据从 Java 拷贝到 native 层,或者从 native 层拷贝到 Java,如果希望减少拷贝,开发更加高效的 Android 音频应用,则建议使用 Android NDK 提供的 OpenSL ES API 接口,它支持在 native 层直接处理音频数据。</p>    <p>OpenSL ES 从 Android 2.3 开始就提供了,但是 Android 官方关于 OpenSL ES 的文档非常少,网上资料也相对贫乏,再加上它的接口采用的是面向对象的 C 接口,不是特别简单易懂,因此学习起来不是那么容易,我计划通过两篇文章来介绍一下这套框架,希望能对初学者有所帮助。</p>    <p>本文不准备介绍 OpenSL ES 的工作原理和函数使用(这些将会在下一篇文章中介绍),而是从宏观的角度简单介绍一下 OpenSL ES 概况,让初学者了解这套 API 是干什么的,可以做哪些事,不能做哪些事,最后给出一些参考示例代码和资源链接。</p>    <h2>1. OpenSL ES 是什么?</h2>    <p>OpenSL ES 全称是:Open Sound Library for Embedded Systems,是一套无授权费、跨平台、针对嵌入式系统精心优化的硬件音频加速API。它为嵌入式移动多媒体设备上的本地应用程序开发者提供标准化, 高性能, 低响应时间的音频功能实现方法,并实现软硬件音频性能的直接跨平台部署,降低执行难度,促进高级音频市场的发展。(来自 <a href="/misc/goto?guid=4959672722012394308" rel="nofollow,noindex">百度百科</a> )</p>    <p>一句话概述:OpenSL ES 是一套针对嵌入式平台的音频标准。</p>    <h2>2. Android 与 OpenSL ES 是什么关系?</h2>    <p>Android 2.3 (API 9) 即开始支持 OpenSL ES 标准了,通过 NDK 提供相应的 API 开发接口,下图是 Android 官方给出的关系图(出处: <a href="/misc/goto?guid=4959672722106731479" rel="nofollow,noindex">这里</a> ):</p>    <p><img src="https://simg.open-open.com/show/a95e6dda10ebc2e7cbce4c247c94cdc4.png"></p>    <p>由该图可以看出,Android 实现的 OpenSL ES 只是 OpenSL 1.0.1 的子集,并且进行了扩展,因此,对于 OpenSL ES API 的使用,我们还需要特别留意哪些是 Android 支持的,哪些是不支持的,具体相关文档的地址位于 NDK docs 目录下:</p>    <pre>  NDKroot/docs/Additional_library_docs/opensles/index.html  NDKroot/docs/Additional_library_docs/opensles/OpenSL_ES_Specification_1.0.1.pdf</pre>    <h2>3. 可以做什么?不能做什么?</h2>    <p>下面总结一下 Android OpenSL ES 的特点以及不支持的功能。</p>    <p>特性:</p>    <p>- C 语言接口,兼容 C++,需要在 NDK 下开发,能更好地集成在 native 应用中</p>    <p>- 运行于 native 层,需要自己管理资源的申请与释放,没有 Dalvik 虚拟机的垃圾回收机制</p>    <p>- 支持 PCM 数据的采集,支持的配置:16bit 位宽,16000 Hz采样率,单通道。(其他的配置不能保证兼容所有平台)</p>    <p>- 支持 PCM 数据的播放,支持的配置:8bit/16bit 位宽,单通道/双通道,小端模式,采样率(8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 Hz)</p>    <p>- 支持播放的音频数据来源:res 文件夹下的音频、assets 文件夹下的音频、sdcard 目录下的音频、在线网络音频、代码中定义的音频二进制数据等等</p>    <p>不支持:</p>    <p>- 不支持版本低于 Android 2.3 (API 9) 的设备</p>    <p>- 没有全部实现 OpenSL ES 定义的特性和功能</p>    <p>- 不支持 MIDI</p>    <p>- 不支持直接播放 DRM 或者 加密的内容</p>    <p>- 不支持音频数据的编解码,如需编解码,需要使用 MediaCodec API 或者第三方库</p>    <p>- 在音频延时方面,相比于上层 API,并没有特别明显地改进</p>    <p>4. 用 OpenSL ES 开发音频应用有什么好处 ?</p>    <p>- 避免音频数据频繁在 native 层和 Java 层拷贝,提高效率</p>    <p>- 相比于 Java API,可以更灵活地控制参数</p>    <p>- 由于是 C 代码,因此可以做深度优化,比如采用 NEON 优化</p>    <p>- 代码细节更难被反编译</p>    <p>- 其他,待添加</p>    <h2>5. 示例代码</h2>    <p>有个老外(Victor Lazzarini)为 Android OpenSL ES API 写了一篇不错的介绍,并给出了一些示例代码,链接如下:</p>    <p><a href="/misc/goto?guid=4959668422578369943" rel="nofollow,noindex">https://audioprograming.wordpress.com/2012/03/03/android-audio-streaming-with-opensl-es-and-the-ndk/</a></p>    <p>我提取了其中的两个文件,修改了一下,整理到我的 AudioDemo 示例中了,个人觉得有更好地演示效果,地址如下:</p>    <p><a href="/misc/goto?guid=4959672715575343159" rel="nofollow,noindex">https://github.com/Jhuster/AudioDemo</a></p>    <h2>6. 有哪些不错的资源 ?</h2>    <p><a href="/misc/goto?guid=4959672722251233461" rel="nofollow,noindex">《OpenSL ES Basics》</a></p>    <p><a href="/misc/goto?guid=4959672722334484653" rel="nofollow,noindex">《Native Audio: OpenSL ES for Android》</a></p>    <p><a href="/misc/goto?guid=4959672722415489083" rel="nofollow,noindex">《Android Audio Architecture》</a></p>    <p><a href="/misc/goto?guid=4959672722500100336" rel="nofollow,noindex">《OpenSL ES for Android》</a></p>    <p><a href="/misc/goto?guid=4959672722580886338" rel="nofollow,noindex">《Tutorials for OpenSL ES for Android》</a></p>    <p>《Android.NDK.Beginner's.Guide.pdf》</p>    <p><a href="/misc/goto?guid=4959672722665534874" rel="nofollow,noindex">《Getting Started with OpenSL on Android》</a></p>    <p><a href="/misc/goto?guid=4959668422578369943" rel="nofollow,noindex">《Android audio streaming with OpenSL ES and the NDK》</a></p>    <h2>7. 小结</h2>    <p>关于如何 Android OpenSL ES API 就介绍到这儿了,文章中有不清楚的地方欢迎留言或者来信 lujun.hust@gmail.com 交流,或者关注我的新浪微博@卢_俊或者 微信公众号 @Jhuster 获取最新的文章和资讯。</p>    <p><img src="https://simg.open-open.com/show/c5f73d6522a6d04df3e90e616662dd9f.jpg"></p>    <p>来自: <a href="/misc/goto?guid=4959672722767154124" rel="nofollow">http://ticktick.blog.51cto.com/823160/1764778</a></p>