[译文]JOAL教程 第四课 进一步了解ALC

来源:互联网 发布:英语四六级软件 编辑:程序博客网 时间:2024/05/18 03:09

[译文]JOAL教程

原文地址:http://jogamp.org/joal-demos/www/devmaster/lesson4.html

原文作者:Athomas Goldberg

译文:三向板砖

转载请保留以上信息。


本次教程对应的学习笔记:http://blog.csdn.net/shuzhe66/article/details/40264341


第四课 进一步了解ALC

 

本文是DevMaster.net(http://devmaster.net/)的OpenAL教程对应的JOAL版本。C语言版原文作者为JesseMaurais


到目前为止,我们遇到的一切复杂问题都交给了Alut来解决,例如处理音频设备等。Alut提供了这些非常不错的功能,但是聪明的编码者总是希望了解它到底做了些什么,我们有时也许会希望直接对ALC进行调用,在这篇教程中我们将一探Alc层并详细了解如何自己处理音频设备[ALC是Audio Library Context的缩写,意为音频库上下文——译者注]。

ALC alc = ALFactory.getALC();String deviceName = "DirectSound3D";// deviceName = null; // 当null作为参数传入alcOpenDevice时将会打开默认设备。ALCdevice device = alc.alcOpenDevice(deviceName);

那么,什么是ALC设备呢?可以将它想象成某种资源,它是OpenAL获取将要使用的音频硬件设备句柄,该句柄被整个系统共享访问。设备是由特定硬件设备在底层的实现,在本例当中我们使用的设备是DirectSound。上面的代码获得了设备的句柄,并对其进行初始化以供程序使用。最后,我们可以看到很多由其它具体声卡实现的对应设备。[这里的”设备”指的是程序上下文中使用的ALCdevice实例,并非指具体的硬件设备,在翻译中,我会使用”硬件设备”来表示真实的物理设备——译者注]

向alcOpenDevice函数传递null参数是完全合法的,这将强制其使用默认设备。


ALCcontext context = alc.alcCreateContext(device, null);alc.alcMakeContextCurrent(context);

什么又是ALC上下文呢?OpenGL程序员也许会想起OpenGL的渲染上下文,不同的上下文控制着窗口不同的渲染状态,通过对’HGLRC’的多次创建来渲染多个窗口,而且,可以为每一个窗口的上下文设置不同的渲染模式。ALC上下文也是同样的道理。首先我们告诉它应当使用哪一个设备(当然是我们已经创建好的),之后我们把这个上下文设置为当前上下文。理论上你可以为不同的听觉情景创建多个渲染上下文,并设置不同的状态变量。虽然“渲染上下文”这一术语一般应用于视觉渲染,但SDK文档中确实使用了这一词汇,所以我在此处也应当使用它。

你可能也注意到了,alcCreateContext的第二个参数被设置为null,Creative Labs的OpenAL SDK中定义了该参数可为下列值之一:

·  ALC_FREQUENCY

·  ALC_REFRESH

·  ALC_SYNC

如果你创建了多个上下文,可以使用alcMakeContextCurrent来在这些上下文中切换。将null传给alcMakeContextCurrent同样是合法的,这将停止任何音频的处理过程。请记住尽管你有多个上下文,但在同一时刻只有一个可以被设置为当前上下文。当你的应用程序需要在两个上下文间交换时,你必须决定哪一个成为当前上下文更加合适。如果你决定做这些工作,即使不对整个系统进行一轮大检测,也能够获得准确的当前上下文的。


ALCcontext curContext = alc.alcGetCurrentContext();

一旦你获得了上下文,你便可以访问到该上下文所使用的设备了。


ALCdevice curDevice = alc.alcGetContextsDevice(curContext);
在上面的代码中,我们使用重新得到的上下文来确定出正在被使用的设备。


Alc中还有另一个非常酷的上下文处理方式:

alc.alcSuspendContext(context);//挂起上下文alc.alcProcessContext(context);//继续上下文

如上所示代码将挂起并继续指定上下文的音频处理。当处理被挂起时,任何送入该上下文的音频数据都不会产生实际的声音。关于渲染上下文还必须提到一点:OpenAL 1.0标准并未明确声明声源与缓冲区可被在不同上下文间复用。声源与缓冲区在应用程序中的生存期持续到其对应ID被销毁之时。(即ID未被删除时都有效)


alc.alcMakeContextCurrent(null);alc.alcDestroyContext(context);alc.alcCloseDevice(device);

上面的代码就是清理无用上下文时需要写的。将当前上下文置为null,并将之前创建的上下文释放,之后设备的句柄会交还给操作系统的资源当中。


还剩下几个未被涉及到的Alc方法:

public int alcGetError();public boolean alcIsExtensionPresent(ALCdevice device, String extName);public int alcGetEnumValue(ALCdevice device, String enumName);public String alcGetString(ALCdevice device, int token);public void alcGetIntegerv(ALCdevice device, int token, int size, int[] dest);

也许它们的功能对你来说是显而易见的,但我们还是一起来好好看一下吧。

首先,alcGetError方法与之前的alGetError十分相似,但它返回的是Alc错误。

之后的两个函数仅仅是为了检测Alc的拓展,这是开发者预留的,目前尚未有这类拓展出现。

最后一个函数,alcGetInteger,当以ALC_MAJOR_VERSION或ALC_MINOR_VERSION做参数时将会返回Alc版本。

 

alcGetString非常的有用,它的token参数可以是下列三值之一:

·  ALC_DEFAULT_DEVICE_SPECIFIER

·  ALC_DEVICE_SPECIFIER

·  ALC_EXTENSIONS

第一个会返回你所使用的OpenAL实现设备名称,这里应当是"DirectSound3D",就像我们上面所用到的那个名字一样。

第二个会返回一个标识符列表,但本例中仅会返回一个"DirectSound"(出于某种原因,并没有"3D"两字)。

最后的参数会返回Alc拓展列表,但这类拓展目前并不存在。

 

以上就是Alc的大部分内容了,我希望通过它你能更好的理解OpenAL与系统的交互方式。你可以尝试一下不使用Alut来初始化你的程序。无论哪种方式都有它的乐趣。



0 0
原创粉丝点击