本文主要是介绍OpenSL ES for Android,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
OpenSL ES for Android
原英文文档地址:http://mobilepearls.com/labs/native-android-api/ndk/docs/opensles/
OpenSL ES (Open Sound Library for Embedded Systems)OpenSL ES - 嵌入式音频加速标准
http://write.blog.csdn.net/postedit/51377317
这篇文档描述了基于Khronos Group OpenSL ES™ 1.0.1标准的安卓原生音频接口。
所有特征适用于安卓API level 9(安卓2.3)及其以上,除非有另外的说明。有些特别指出的特征只对API level 14(安卓4.0)及其以上有效。
OpenSL ES提供了C语言的接口,也可以用C++调用,同时暴露了类似于安卓APIs音频部分 Java调用的的特征:
- android.media.MediaPlayer
- android.media.MediaRecorder
与所有安卓原生开发套件(NDK)相比,OpenSL ES对安卓的首要目的是使用Java代码通过Java本地接口(JNI)调用帮助实现共享库。
NDK不打算用来写纯C/C++程序。也就是说,OpenSL ES是一个全功能的API,我们希望你可以通过只使用这个API就能最大的实现你的音频需求,
而不需要在Dalvik虚拟机上运行电话代码。
新手入门
示例代码
推荐
可用于您自己的代码模型测试的示例代码位于NDK文件目录platforms/android-9/samples/native-audio/下。
不推荐
OpenSL ES 1.0.1规范在附录中包含示例代码(见下方链接的“参考文献”)。然而,附录B中的例子:示例代码和附录C:用例示例代码使用的特征不被安卓支持。
一些例子也包含印刷错误,或者他们使用的API可能会变化。因此需谨慎使用;尽管这些代码可能对帮助理解整个OpenSL ES标准有用,但它不应该在安卓中使用。
在你的程序源代码中增加OpenSL ES
OpenSL ES是一个C的API,但是可以被C和C++代码调用。
在你的代码中至少要添加如下代码:
#include <SLES/OpenSLES.h>
如果你使用安卓扩展,还需要包括头文件:
#include <SLES/OpenSLES_Android.h>
这也会自动包含这些头文件(你不需要包含这些):
#include <SLES/OpenSLES_AndroidConfiguration.h>
#include <SLES/OpenSLES_AndroidMetadata.h>
Makefile
如下编辑你的Android.mk:
LOCAL_LDLIBS += libOpenSLES
音频内容
打包音频内容的方法有很多种,包括:
Resources
将你的音频文件放置在/res/raw/目录下,你就可以通过Resources相关的APIs轻松访问。然而不能直接本地访问资源(resources),
所以你在使用前需编写Java程序将它们拷贝出来。
Assets
将你的音频文件放置在/assets/目录下,你可以通过安卓原生的asset manager APIs直接访问。 更多信息请看APIs文档中的头文件android/asset_manager.h 和
android/asset_manager_jni.h。位于NDK目录 platforms/android-9/samples/native-audio/ 下的示例代码共同使用本地资源管理器和安卓文件描述符数据定位器。
Network
你可以使用URI数据定位直接从网络上播放音频内容。然而,一定要阅读下面的“安全和权限”章节。
Local filesystem
URI数据定位支持的文件:本地文件的计划,提供的文件是应用程序可访问的。注意,安卓安全框架通过Linux用户标识和群组标识机制限制文件访问。
Recorded
你的应用程序可以通过麦克风输入记录音频数据,存储内容然后播放。示例代码使用“Playback”剪辑方法。
Compiled和linked inline
你可以直接连接音频内容到共享库,然后使用音频播放器与缓冲队列数据定位器播放它。这是最适合短的PCM格式的剪辑。
示例代码为“Hello”和“Android”剪辑使用这种技术。PCM数据通过bin2c工具(不提供)转换成了十六进制字符串。
Real-time synthesis
你的应用程序可以在操作的时候合成PCM数据,之后使用音频播放器播放它。这是一个相当先进的技术,但这个音频合成的细节超出了文章的范围。
虽然发现和创造有用的音频内容超出了这篇文章的内容,但是可以查看下方“参考文献”章节中推荐的网站进行搜索。
注意,出于录制内容隐私方面的考虑,需确保你有合法权限去播放和录制音频。
Debugging
针对鲁棒性,我们建议你检查由大多数API返回的SLresult值。使用断言(assert)与更高级的错误处理逻辑是一个编程风格个特定的API问题;
详情请见维基百科中关于assert的文章。在提供的例子中,我们已经为了“不可能”的条件使用了断言,这将指示别人可能在生产中发生的编码错误,并明确的进行错误处理。
很多API错误导致日志条目,除了非0结果代码。这些日志条目提供了额外的信息,对更多复杂的API,如Engine::CreateAudioPlayer,相当有用。
使用adb logcat, Eclipse ADT 插件日志窗口,或者ddms logcat查看日志。
OpenSL ES1.0.1支持的特征
该章节总结了可用的特征。在一些情况下,会有一些限制,这将在下一个分章节中描述。
全局切入点
支持的全局切入点:
- slCreateEngine
- slQueryNumSupportedEngineInterfaces
- slQuerySupportedEngineInterfaces
对象和接口
下表显示了安卓OpenSL ES实现支持的对象和接口。绿色表示的是支持的特征。
限制
此章节相对于上一章节中支持的对象和接口的限制进行了详述。
Buffer queue data locator
一个带有缓冲队列数据定位器的音频播放器或录制器仅支持PCM数据格式。
Device data locator
I/O设备数据定位器唯一支持的用途是当它被指定为Engine::CreateAudioRecorder的数据源。它应该像下面显示的例子那样初始化:
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
Dynamic interface managemet
支持RemoveInterface和ResumeInterface。
Effect combinations
在相同的输出环境中同时拥有混响和预设混响是没有意义的。
如果估计的CPU负载太高,平台可以忽略效果要求。
Effect send
SetSendLevel 支持每个音频播放器单个发送水平。
Environmental reverb
环境混响不支持反射延时,反射层,或者结构SLEnvironmentalReverbSettings的混响延时领域。
MIME data format
MIME数据格式只能被URI数据定位器使用,并且只能用于播放器(不是录制器)。
OpenSL ES的安卓实现需要mineType初始化成NULL或一个有效的UTF-8字符串,containerType初始化成一个有效值。不考虑其他情况下,例如移植到其他实现,或者不能由报头标识的内容格式,我们建议你将mimeType设置成NULL或者将containerType设置成SL_CONTAINERTYPE_UNSPECIFIED。
支持的格式包括WAV PCM,WAV ALWAW,WAV ULAW, MP3,Ogg Vorbis, ACC LC, He-AACv1(aacPlus),HE-AACv2(增强的addc aacPLus),ARM,和 FLAC[前提是这些被整个平台支持,还有AAC格式必须位于MP4或者ADTS容器内]。不支持MIDI。WMA不是开源发布的,它于安卓OpenSL ES的兼容性还没有被验证。
OpenSL ES的安卓实现不支持DRM的直接回放和内容加密;如果你想播放它,你需要在播放前将你的应用转换成明文,还要执行程序中任何DRM限制。http://write.blog.csdn.net/postedit/51377317
Object
不支持Resume,RegisterCallback, AbortAsyncOphttp://write.blog.csdn.net/postedit/51377317eration,SetPriority,GetPriority,和SelLossOfControlInterfaces。
PCM data format
PCM数据格式可只被缓冲队列使用。支持PCM回放配置是8位无符号或16位带符号,单声道或立体声,低字节序和这些采样率:
8000,11025,12000,16000,22050,24000,32000,44100,4800赫兹。对于录音,支持的配置与设备有关,一般可用16000赫兹16位单声道。
注意samplesPerSec实际上是毫赫兹单位,不要被名字误导。为了避免意外使用错误的值,你应该使用符号常量初始化(例如SL_SAMPLINGRATE_44_1)。
Playback rate
支持的播放速率范围和性能根据平台版本和实现方式而异,因此需在运行时通过PlaybackRate::GetRateRange
or或PlaybackRate::GetCapabilitiesOfRate
查询来确认。http://write.blog.csdn.net/postedit/51377317
也就是说,一些典型速率范围的指导可能是有用的:在安卓2.3通常支持单一的播放速率范围从500千分率到2000千分率,属性SL_RATEPROP_NOPITCHCORAUDIO
。在安卓4.0中PCM格式的数据源支持同样的速率范围,其他格式是单位速率范围。
Record
不支持SL_RECORDEVENT_HEADATLIMIT
和 SL_RECORDEVENT_HEADMOVING事件。
Seek
SetLoop 允许整个文件循环。startPos参数应该为0同时endPos参数应该为SL_TIME_UNKNOWN。
URI data locator
URI数据定位器可以只被MIME数据格式使用,只用于音频播放器(不是录音器)。支持scheme http:和file:。缺少scheme默认为file:scheme。
其他schemes如https:, ftp:, content:不支持。rtsp:没有验证过。
数据结构
安卓支持OpenSL ES1.0.1数据结构:
- SLDataFormat_MIME
- SLDataFormat_PCM
- SLDataLocator_BufferQueue
- SLDataLocator_IODevice
- SLDataLocator_OutputMix
- SLDataLocator_URI
- SLDataSink
- SLDataSource
- SLEngineOption
- SLEnvironmentalReverbSettings
- SLInterfaceID
平台配置
安卓OpenSL ES是为多线程应用设计的,它是线程安全的。
安卓OpenSL ES支持每个应用单个引擎,高达32个对象。可用设备内存和CPU可能进一步限制了对象的可用数量。
slCreateEngine承认,但忽略这些发动机选项:
SL_ENGINEOPTION_THREADSAFE
SL_ENGINEOPTION_LOSSOFCONTROL
OpenMax AL和OpenSL ES可以在同一个应用中一起使用。在这个情况下,内部有一个单一的共享引擎对象
,32个在OpenMax和OpenSL ES之间共享的对象限制。应用首先就应该创建这两个引擎,然后使用这两个引擎,最后销毁这两个引擎。这个实现坚持在共享引擎引用计数,因此它在第二次销毁的时候会被正确销毁。
这篇关于OpenSL ES for Android的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!