Tinkering with Source and Listener Properties

Now that basic playback capabilities are understood, let’s venture further. Often in a game, a sound may be too modified in some ways from its raw, normal format. JOAL provides the basic functionality internally to modify these properties. Let’s look first at the changes that can be applied to the Listener.

Listener Properties

Earlier on, the list of properties were given but not implemented. Let’s look at how some of these properties can be adjusted for use within a game.

In most games, the Listener is going to be at the same point as the character. Because most players tend to move around in games, the Listener should update its position with accordance to the player’s current movement. JOAL is capable of processing and rendering the audio based on the Distance Models described earlier in this chapter. This ability is important because it takes the work away from the programmer of determining how a sound will be received at the Listener. Consider a game that uses the Actor class presented in Chapter 2. Updating the position of the Listener based on the current position of the class is a fairly trivial adjustment. This function takes three floating-point values to set the new location of the Listener.

void setListenerPosition(int x, int y, int z)   {     al.alListener3f(AL.AL_POSITION,x,y,z);   }

We can easily plug in the current position of the Actor to move the Listener, as follows:

setListenerPosition(Actor.getX(),Actor.getY(),Actor.getZ();

Using this method, we can automatically update the position of the Listener based on the position of the Actor. Using this function in this manner is most likely to set the Listener to the center of the mass of the object. Given that a player is likely to move each frame, this method should be called frequently enough to keep up with the player. Feel free to modify the parameters if the camera system or other game requirements are needed to properly position the Listener.

The other main position-oriented Listener attribute is the orientation. The orientation is expressed as the “at” and “up” vectors that describe the facing of the object. The OpenAL specification expects these vectors to be orthogonal to each other. When making a linkage to a 3D rendering, these vectors are usually the same as the camera view when set at the player’s perspective as in a First-Person Shooter (FPS) game.

A quick function that can set the orientation of the Listener follows:

void setListenerOrientation(float[] orientation)   {     al.alListenerfv(AL.AL_ORIENTATION,orientation);   }

This function takes a float array that holds the current vectors in a single location. Some applications may need to use separate values in these spaces, then combine them when passing through to the actual setting method. Make sure that the vectors are properly calculated for the game in question. For a quick refresher on 3D transformations, see Chapter 12, “3D Graphics Foundations.”

Additional controls for the Listener include setting gain and velocity. Velocity is identical to setting the position, but with one clear distinction. The term velocity is used here to determine how the rendering context will process the Doppler effects to give the Listener a correct view of the sound from an arbitrary position. Velocity does not involve updating the position of a Listener or other object. Make sure to keep this distinction clear when using JOAL.

The last Listener control remaining is the gain. To set the gain at the Listener, use one of the float methods to modify the gain value, as shown in the following code:

void setGain(float gain)     {         al.alListenerf(AL.AL_GAIN, gain);     }

This method allows the sounds at the Listener to be increased or reduced by a floating-point value. Passing a value of 1.0 will result in a sound that is not modified. Remember that only one valid Listener class per rendering context exists, so modifying the gain changes the value for all sounds being rendered for the Listener in question.

Now let’s look at the modification of Source properties. Because any number of Sources can be in a game, the functions available to them are fairly extensive. This section discusses the most functions that can be used for game development.

Source Properties

Several properties of particular importance regarding Source control are available. One of the most important is the distinction about how the Source will be rendered in relation to the player. If a game needs a sound to always play at a fixed distance from the Listener, it should be set to AL_SOURCE_RELATIVE, as follows:

al.alSourcei (source[0], AL.AL_SOURCE_RELATIVE, buffer[0]);

Sounds that are generated from a sidekick or a weapon are likely candidates for being rendered with respect to the Listener at all times.

In most games, Sources often represent enemies or other environmental audio components. Many of these Sources never move in the world and await the appearance of the Listener before ever doing any real work. When setting up the game world or applying sounds to mobile Actors and Object, it is important to be able to quickly update the positional properties related to a given Source. The AL_SOURCE_RELATIVE property has already been discussed, so let’s move on to the particulars of setting object positions that are not to be immediately relative to the Listener.

To set the position of a source using Cartesian coordinates, plug in the following code:

al.alSource3f(source[0], AL.AL_DIRECTION,0,0,0);

This property must be set for each additional sound that is loaded and prepared for play in a game. Remember that the last three parameters of this method are the x-, y-, and z-locations within the world. Look at Figure 4.3 to see how the Sources may be positioned in relation to the Listeners sitting at the origin.

image from book
Figure 4.3: Sample Source positions with respect to the origin.

As Figure 4.3 shows, the position behind the player is considered to be a positive z-value, whereas the Source in the front right of the Listener is at the –2 z-position. The 3D coordinate system might take some time to get used to for newcomers. Tinker around with positions and values until this process becomes rote. To properly position sounds in 3D, knowledge of the coordinate system is imperative.

Numerous additional Source properties can be used. Several of these have been discussed earlier in the chapter. Now let’s look at a few quick code samples to demonstrate the use of the controls that were not yet discussed.

To set the pitch of a Source:

al.alSourcef (source[0], AL.AL_PITCH,1.0f);

When setting the pitch, 1.0 causes no adjustment to the pitch. Remember that 0 is not a valid argument for this function call.

To set the gain of a Source:

al.alSourcef (source[0], AL.AL_GAIN,1.0f);
Note 

A value of 1.0 represents no change in the gain of the Source. This value is ultimately capped by the gain values of the Listener, so bear that in mind while muting or increasing the gain of the Source.

To apply a direction to a Source:

al.alSourcefv(source[0],AL.AL_DIRECTION,direction);

where direction is defined as an array of three floating-point values. When this property is set to the 0 vector, the direction is considered to be symmetric about the vector. To restore the Source to nondirectional, just pass back the 0 vector as follows:

al.alSource3f(source[0], AL.AL_DIRECTION,0,0,0);

It’s a good idea to carefully organize Sources in the game so they aren’t accidentally muted or set incorrectly.

Tinkering with the Doppler Effect

There is one more point of interest with regard to sound rendering in JOAL—the Doppler effect. The Doppler effect describes how auditory perception is changed when objects move relative to a sound source. JOAL and OpenAL try to emulate the real-world rendering of sound by including the Doppler effect as a parameter that can be manipulated by programmers.

JOAL provides two functions that allow the user to modify the Doppler values used to calculate the audio rendering described previously. These functions are alDopplerFactor() and alDopplerVelocity(). The alDopplerFactor() allows the user to modify how great the Doppler effect is presented within the game. Any positive value from 0.1 to 1.0 adjusts the way sound is rendered but also has the side effect of modifying the reality of how the sound is rendered to the Listener. The default Doppler value is 1.0. To turn the Doppler effect off completely, pass a 0 to this method.

When creating sounds in a strictly 2D environment, the Doppler effect is not likely to be needed. Processing the Doppler effect may affect performance on low-power systems as well as in games where the rendering thread has a high priority.

The second method is alDopplerVelocity(), which modifies the effective speed of sound within the application. This method requires a nonnegative, nonzero value; otherwise, the call is ignored. The default value is set to 343 and was designed to give the same speed that sound has in the real world. OpenAL does not maintain a sense of units, so if this value is modified, make sure that all the related values in the world are consistent. To use these methods, simply call the following:

al.alDopplerFactor(.99); al.alDopplerVelocity(500);

Tinkering around with these methods is good for countless hours of enjoyment.



Practical Java Game Programming
Practical Java Game Programming (Charles River Media Game Development)
ISBN: 1584503262
EAN: 2147483647
Year: 2003
Pages: 171

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net