• entries
235
509
• views
172604

# Sound And Fury

127 views

Well, I got the sound engine reworked last week. It now uses SDL_Mixer. It seems to work well enough for our purposes, although it's missing pitch shifting ( doppler ).

In the process of converting from FMOD, I fixed numerous lingering sound issues. One of the most major ones was a bug from the transition from sound files to sound tags. In order to allow our sound designer to swap out sounds at runtime, and also to facilitate localization, I added a .csv file that points from a sound tag string to the sound file name itself. All level and entity data, as well as the engine now only uses sounds by tag and not by file. Of course, there were still some sound sources using the old system, and they were not being attenuated properly, making some environmental sounds appear as if they were everywhere.

I also added a tiny bit of fake HRTF - basically slightly dimming the sound if directly in front of you, and dimming it more if directly behind you. Both effects go away as a sound is more directly in one ear.

One of the major feedback points from our alpha test was the lack of 'stuff' in the levels - specifically vegetation. Vegetation is nice, b/c it tends to have a lot of interesting surfaces to catch the light, it moves around, and can provide a sense of age when used to cover things normally not covered in vegetation.

Right now, we can have static entity plants, or burned-in triangular static trees, but neither are designed to move in any meaningful way.

So, I implemented a Jakobsen-style verlet constraint system. Right now this is only used as a particle system, and can be used to model ropes, springs, sticks, cloth or any combination of the above. Last night I got it into the engine and rendering ( although without lighting or shadows ), and even added world and entity collision.

Here is a shot of several pieces of rope, one of which is stuck on the forcefield.

My plan is to use the cloth for well, cloths like banners, and flags, but also for patches of ivy, and viny tangles, spiderwebs, etc.

For lighting, I have several ideas, but the one I'm sure will look good, but may be too expensive in some cases, is to do shadow raycast checks over several frames ( like the entities do ). Now the entities do this once per object per frame per light, but to get good results on a long rope, I suspect I will need to do all or several vertices. Perhaps just the rope ends and the cloth corners will be enough... we'll see...

I'd be interested in seeing how you do locational sound with SDL_mixer. I have sound that is equal volume and balance no matter where it comes from, and I think it kind of ruins the experience.

I also have a tiny bit of hope in my heart that since you are using SDL_mixer, you are also using SDL and OpenGL, and will port the game to the Mac (or are looking for someone who can). But I know at least the last part is untrue, unless you want to scoop up the gaming market over there (which seems to have worked for Professor Fizzwizzle, but probably not for a more 'hardcore' title). [crying]

I just use the effect calls to attenuate distance, and set the panning...

            // calculate volume & panning

D3DXVECTOR3 delta_p( listener.pos - anInstance.mPosition );

D3DXVECTOR3 delta_v( listener.vel - anInstance.mVelocity );

// make sounds behind you somewhat quieter

// first create basis

D3DXVECTOR3 up( YAxis );
D3DXVECTOR3 at( listener.facing );

D3DXVECTOR3 right;

D3DXVec3Cross( &right, &at, &up );

D3DXVec3Normalize( &right, &right );

D3DXVECTOR3 d_p;
D3DXVec3Normalize( &d_p, &delta_p );

float32 amount_right = D3DXVec3Dot( &right, &d_p);

// now left right is in [-1,1]

// now convert into left and right ints

if ( global_pan_separation > 0.0f )
{
amount_right *= ( global_pan_separation );

//                amount_right
Math::Clamp( amount_right, -1.0f, 1.0f );

float32 amount_left = -amount_right;

int32 left = 0;
int32 right = 0;

if ( amount_left > 0.0f )
{
left  = int32( ( 1.0f + amount_left ) * 127.0f );
right = int32( ( 1.0f - amount_left ) * 127.0f );
}
else
{
left  = int32( ( 1.0f - amount_right ) * 127.0f );
right = int32( ( 1.0f + amount_right ) * 127.0f );
}

Mix_SetPanning( anInstance.mChannel, left, right );
}

// see if it's behind you
float32 dist = D3DXVec3Length( &delta_p ) / max_distance;
float32 volume = sqrtf( dist );

Math::Clamp( volume, 0.0f, 1.0f );

// if it's behind you, decrease the volume somewhat

float32 muffle_amount = -D3DXVec3Dot( &listener.facing, &d_p );

if ( muffle_amount < 0.0f )
{
const float32 alpha = fabsf( muffle_amount );
const float32 muffling = alpha * behind_muffle + ( 1.0f - alpha ) * 1.0f;

volume *= ( muffling );
}
else
{
const float32 alpha = fabsf( muffle_amount );
const float32 muffling = alpha * front_muffle + ( 1.0f - alpha ) * 1.0f;

volume *= ( muffling );
}

Mix_SetDistance( anInstance.mChannel, min( 255, max( 1, (uint8)( volume * 255.0f ) ) ) );

[\source]


I just trying to look up how to do that today. The papers I read said you had to do a high frequency filter to muffle the sound to make it sound correct. I was already panning and attenuating but now I'll have to try to muffle the sound for front and back.

Thanks :)

## Create an account

Register a new account