OpenAL Lesson 4: The ALC(转载)

转载 2007年10月14日 19:59:00

转载http://www.devmaster.net/articles/openal-tutorials/lesson4.php

Up until now we have been letting Alut do all the real tricky stuff for us. For example handling the audio devices. It's really nice that the Alut library is there to provide this functionality, but any smart coder will want to know exactly what their doing. We may want to, at some point, use the Alc directly. In this tutorial we will expose the Alc layer and take a look at how to handle the devices on our own.

ALCdevice* pDevice;

ALCubyte DeviceName[] 
= "DirectSound3D";

pDevice 
= alcOpenDevice(DeviceName);

So what is an Alc device? Try to think of it in terms of a resource. OpenAL grabs a handle to the hardware being used, which must in turn be shared with the entire system. A device can be of a specific implementation as well, as in this case where we are using DirectSound as the audio device. This code grabs a handle to the hardware device and readies it to be used by the application. Eventually we should see more devices made for specific soundcards.

Passing NULL to 'alcOpenDevice' is a perfectly valid argument. It forces the Alc to use a default device.

ALCcontext* pContext;

pContext 
= alcCreateContext(pDevice, NULL);

alcMakeContextCurrent(pContext);

What is an Alc context? OpenGL coders will recall that there was rendering contexts used by OpenGL that controlled the state management across different windows. An 'HGLRC' as they are called could be created several times to enable multiple rendering windows. And different rendering states for each context could be achieved. An Alc context works on the same principal. First we tell it which device to use (which we have already created), then we make that context current. In theory you could create multiple rendering contexts for different windows, and set the state variables differently and have it work just fine. Although the term "rendering context" usually applies to a visual rendering, this is the term preferred in the sdk docs and should be the term used.

You may notice too that the second parameter in 'alcCreateContext' has been set to NULL. The OpenAL sdk from Creative Labs defines the following variables which are optional flags to that parameter.

  • ALC_FREQUENCY
  • ALC_REFRESH
  • ALC_SYNC

If you were to create multiple contexts you could make them interchangeable by making a call to 'alcMakeContextCurrent'. Sending NULL to 'alcMakeContextCurrent' is also a perfectly valid argument. It will prevent processing of any audio data. Be aware that even if you have multiple rendering contexts, you can only have one current at a time, and when your application needs to use two contexts interchangeably you must be the one to make sure the appropriate context is current. And if you do decide to do this, then there may be times when you want to know exactly which context is current without going through a big check.

ALcontext* pCurContext;
pCurContext 
= alcGetCurrentContext();

Once you have your context you can also obtain the device in use by that context.

ALdevice* pCurDevice;
pCurDevice 
= alcGetContextsDevice(pCurContext);

Above we used the context we retrieved to find out which device it was using. There is also one other cool feature that was built into Alc for handling contexts.

alcSuspendContext(pContext);
// Processing has been suspended to pContext.
alcProcessContext(pContext);
// Processing has been re-enabled to pContext.

What we have done above was stop, and then resume processing of audio data to the context. When processing has been suspended, no sound will be generated from data sent through that context. A further note on the rendering context: the OpenAL 1.0 spec does imply, but does not explicitly say, that sources and buffers may be used across contexts. The "lifetime" of a source or buffer during the application, is said to be valid as long as the source and buffer id is valid (i.e. they have not been deleted).

alcMakeContextCurrent(NULL);
alcDestroyContext(pContext);
alcCloseDevice(pDevice);

And that is how we clean up. The current context is defaulted to NULL, the context we created is released, and the handle to the device is given back to the system resources. There is but a few more Alc functions we have not yet covered.

ALenum alcGetError(ALvoid);

ALboolean alcIsExtensionPresent(ALCdevice
* device, ALubyte* extName);

ALvoid
* alcGetProcAddress(ALCdevice* device, ALubyte* funcName);

ALenum alcGetEnumValue(ALCdevice
* device, ALubyte* enumName);

ALubyte
* alcGetString(ALCdevice* device, ALenum token);

ALvoid alcGetIntegerv(ALCdevice
* device, ALenum token, ALsizei size, ALint* dest);

It may be pretty obvious to you what these do, but lets humour ourselves and have a closer look. First we have 'alcGetError' which is just like 'alGetError' but will return Alc errors. The next three functions are for querying Alc extensions. This was just the creators planning ahead, as there are no Alc extensions either. The last function, 'alcGetInteger', will return the Alc version when passed 'ALC_MAJOR_VERSION' or 'ALC_MINOR_VERSION'.

The function 'alcGetString' is pretty cool. It can take any of the following three parameters to 'token':

  • ALC_DEFAULT_DEVICE_SPECIFIER
  • ALC_DEVICE_SPECIFIER
  • ALC_EXTENSIONS

The first will return the device string which your OpenAL implementation will prefer you to use. In current OpenAL this should be "DirectSound3D", like we used above. The second token will return a list of specifiers, but in current OpenAL will only return "DirectSound" (without the "3D" for some reason). The last will return a list of Alc extensions, of which none exist yet.

Well that's most of Alc for you. I hope it gave you a better understanding of how OpenAL interacts with the operation system. You might try writing your own initialization routines so you can cast off Alut altogether. Either way have fun with it.

 

使用openal播放WAV音频

不使用alut,只使用openal播放WAV文件: #include #include struct WAVE_Data { char subChunkID[4]; //should con...
  • u011417605
  • u011417605
  • 2015年11月05日 18:48
  • 1184

OpenAL播放WAV音频文件

#include"al.h" #include"alc.h" #include"alut.h" #include #include #include #include /* 你会发现再O...
  • cp790621656
  • cp790621656
  • 2014年06月23日 00:48
  • 1551

cocos2dx之音效引擎

在游戏中,我们把声音分为两类。第一类是音乐,这种类型的声音通常长度较长,适合作为环境音乐(例如游戏的背景音乐)。由于它的长度较长,同一时刻通常只能播放一首音乐。第二类是音效,它的特点是长度很短,但是可...
  • ganpengjin1
  • ganpengjin1
  • 2014年01月17日 10:38
  • 24685

IOS音频4:之采用四种方式播放音频文件(四)AudioToolbox AVFoundation OpenAL AUDIO QUEUE

3.1 任务需求分析    在本小节主要利用openal实现对音频文件的播放。在功能上需要实现可以利用ply_music 按钮播放本地音频文件。界面上我们沿用2.1小节中所建立的工程,在-(IBAct...
  • u014011807
  • u014011807
  • 2014年10月21日 10:28
  • 1345

MQL4语言开发课程lesson1517

  • 2008年12月05日 20:32
  • 2.06MB
  • 下载

7 Days To Complete Search Engine Domination - Lesson 4 (pdf)

  • 2010年04月28日 08:41
  • 60KB
  • 下载

新概念4 lesson1

  • 2009年03月06日 08:36
  • 21KB
  • 下载

新概念4lesson2

  • 2009年03月06日 08:37
  • 21KB
  • 下载

[北京圣思园Java培训教学视频]Java.SE.Lesson.4_code.rar

  • 2012年09月23日 21:42
  • 263KB
  • 下载

Lesson 4 Are you a teacher

  • 2013年08月10日 12:21
  • 1.09MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenAL Lesson 4: The ALC(转载)
举报原因:
原因补充:

(最多只允许输入30个字)