Fundamentals of Audio and Video Programming for Games (Pro-Developer)

If you want your program to support EAX 2.0 environmental settings, set the following global definition at the beginning of your source code, before the  Concertina.h header is included (see this code at the beginning of the  Concertina.cpp file).

#define EAX 1

If you do not wish to support EAX, then comment this line out (or delete it altogether).

If you set the EAX define to 1, then the header file  eax.h is included by  Concertina.h , and a range of methods becomes available to you to drive the EAX hardware, if the user has it available (see Chapter 7 on using property sets and EAX 2.0 extensions). The initialization of property set interfaces is not dependent on either EAX hardware or the inclusion of the header, so this is always completed by the initialization process. These property set interfaces could, of course, be used for implementations other than EAX, if you were to add the methods to the Concertina class. We have implemented EAX as the one that you will probably most want to include in your application.

The first method simply sets one of the preset EAX 2.0 environments.

bool SetEAXPresetEnvironment(int envNumber);

For example, to set the Psychotic environmental reverb on all sounds in your game, use this simple call.

SetEAXPresetEnvironment(PSEAX_ENVIRONMENT_PSYCHOTIC);

If you want to define some of your own EAX environments, add them to the following enumeration and structure in  Concertina.h .

enum EAX_ENVIRONMENT_ID { EAXID_submarine, EAXID_canyon, // Terminate the enumeration with this value. EAXID_end }; struct eaxEnvironmentStruct eaxEnvironment[] = { { EAXID_submarine, {-1000, -1000, 0.0f, 2.8f, 0.1f, 429, 0.0f, 1023, 0.0f, EAX_ENVIRONMENT_SEWERPIPE, 1.7f, 0.8f, -5.0f, 63}, EAXID_canyon, {-1000, -698, 0.0f, 7.2f,0.3f,-1166, 0.0f, 16, 0.0f, EAX_ENVIRONMENT_AUDITORIUM, 36.2f, 1.0f, -5.0f, 63}, // Terminate this structure with the end value. EAXID_end };

Note that in this case, unlike the string used to provide settings for the special effects, we are filling in an EAXLISTENERPROPERTIES structure. (For example, the values listed for the submarine are in the correct order for the EAXLISTENERPROPERTIES structure). There are code comments in  Concertina.h that make this easier. This way, you can add as many of your own environments as you want, and then the call to set these environments is very simple.

bool SetEAXALLListenerProperties(EAX_ENVIRONMENT_ID eax_ID);

Here is an example.

SetEAXALLListenerProperties(EAXID_canyon);

If you wish to change just a few of the properties of EAX listener, there are two methods that you can use. The first method sets new flags.

bool SetEAXListenerFlags(DWORD newFlags);

To turn off all flags except EAXLISTENERFLAGS_DECAYHFLIMIT , which limits high-frequency decay time according to air absorption , make the following call.

SetEAXListenerFlags(EAXLISTENERFLAGS_DECAYHFLIMIT);

The second method allows you to set from one to seven of the properties of the EAX listener at once. Note that to enter long properties, the value should be entered as a float.

void SetEAXListenerProperties(DSPROPERTY_EAX_LISTENERPROPERTY p0, float v0, DSPROPERTY_EAX_LISTENERPROPERTY p1 = DSPROPERTY_EAXLISTENER_NONE, float v1 = 0.0f, DSPROPERTY_EAX_LISTENERPROPERTY p2 = DSPROPERTY_EAXLISTENER_NONE, float v2 = 0.0f, DSPROPERTY_EAX_LISTENERPROPERTY p3 = DSPROPERTY_EAXLISTENER_NONE, float v3 = 0.0f, DSPROPERTY_EAX_LISTENERPROPERTY p4 = DSPROPERTY_EAXLISTENER_NONE, float v4 = 0.0f, DSPROPERTY_EAX_LISTENERPROPERTY p5 = DSPROPERTY_EAXLISTENER_NONE, float v5 = 0.0f, DSPROPERTY_EAX_LISTENERPROPERTY p6 = DSPROPERTY_EAXLISTENER_NONE, float v6 = 0.0f, DSPROPERTY_EAX_LISTENERPROPERTY p7 = DSPROPERTY_EAXLISTENER_NONE, float v7 = 0.0f);

A typical call to this method would set a range of the listener properties.

SetEAXListenerProperties(DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, 50.0f, DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION, 0.9f, DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF, -10.0f);

There is nothing magic about having a maximum of seven properties; you could extend this method to take more if necessary. Or if you required, say, nine properties to change, simply make two calls, one for seven properties and one for two.

The range of methods for setting source buffer properties is similar, except of course we have to pass in a sound ID, as we are only setting the properties for the sound source, and not for all sounds. Again, the following method to change source properties can affect up to seven elements.

void SetEAXSourceProperties(soundBufferRef* sID, DSPROPERTY_EAX_BUFFERPROPERTY p0, float v0, DSPROPERTY_EAX_BUFFERPROPERTY p1 = DSPROPERTY_EAXBUFFER_NONE, float v1 = 0.0f, DSPROPERTY_EAX_BUFFERPROPERTY p2 = DSPROPERTY_EAXBUFFER_NONE, float v2 = 0.0f, DSPROPERTY_EAX_BUFFERPROPERTY p3 = DSPROPERTY_EAXBUFFER_NONE, float v3 = 0.0f, DSPROPERTY_EAX_BUFFERPROPERTY p4 = DSPROPERTY_EAXBUFFER_NONE, float v4 = 0.0f );

A typical use of this would be to set obstruction or occlusion properties. Assuming that you had a sound ID for an engine, and the vehicle was about to pass behind an obstruction, you could use the following code.

SetEAXSourceProperties(&sIDEngine, DSPROPERTY_EAXBUFFER_OBSTRUCTION, -2000.0f, DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO, 0.5f);

Typically, a call like this would be preceded by a call to reset the source buffer defaults, eliminating any leftover settings from previous obstructions or occlusions. Use the following call to reset the defaults.

bool ResetEAXSourceDefault(soundBufferRef* sID);

So, to reset our engine source buffer settings, use this call.

ResetEAXSourceDefault(&sIDEngine);

Finally, there is a call to change the source buffer flags.

bool SetEAXSourceFlags(soundBufferRef* sID, DWORD newFlags);

This is simply shown here for completeness, as in most cases, you want the flags to remain at their defaults. See Chapter 7 for details on how to obtain the EAX 2.0 documentation.

Категории