Updated: October 6th 2003
Overview of a typical soundscript
Below is an example soundscript, in a very small font. We will go over
the various codes and sections in chapters to follow. For now, examine
the following code and orient yourself to the general layout.
>>When someone is in the driver seat, this sound is played.
** Sound pathname with relative references for mod name and sound
quality
newPatch
####################
### Engine Start ###
####################
load @ROOT/Sound/@RTD/DesertCombat/Humvee/Humvee_Start.wav
minDistance 1
dopplerOff
priority -2
*** Distance Volume ***
beginEffect
controlDestination Volume
controlSource Distance
envelope Ramp
param 50
param 100
param 1
param -1
endEffect
>> Sound played at low engine output.
##############
### Lo RPM ###
##############
load @ROOT/Sound/@RTD/DesertCombat/Humvee/Humvee_Low.wav
loop
volume 1
minDistance 2 ** Sound begins fading naturally
2m from source.
relativePosition 0/0/0
priority 8
*** Engine start ***
beginEffect
controlDestination Volume
controlSource Time
envelope Ramp
param 0.2
param 0.8 ** Sound
fades from silence to full volume between 0.2 and 0.8 seconds after engine
start.
param 0
param 1
endEffect
*** Engine Pitch ***
beginEffect
controlDestination Pitch
controlSource Default
envelope Linear
param 0.9
param 0.8
endEffect
*** Distance Volume ***
beginEffect
controlDestination Volume
controlSource Distance
envelope Ramp
param 15
param 65
param 1
param -1
endEffect
*** Engine Volume ***
beginEffect
controlDestination Volume
controlSource Default
envelope Ramp
param 0
param .9
param 1
param -1
endEffect
*** Engine stop ***
beginEffect
controlDestination Volume
controlSource TimeRelease
envelope Ramp
param 0
param 0.2 **
Sound fades so silence and terminates 0.2 seconds after after engine stops.
param 1
param -1
endEffect
>>Sound played after engine picks up speed.
################
### Hi RPM 1 ###
################
load @ROOT/Sound/@RTD/DesertCombat/Humvee/Humvee_Medium.wav
loop
minDistance 8
relativePosition 0/0/0 **
Sound origin is centered on vehicle. Values are x/y/z.
priority 8
*** Engine start ***
beginEffect
controlDestination Volume
controlSource Time
envelope Ramp
param 0.2
param 0.8
param 0
param 1
endEffect
*** Engine Pitch ***
beginEffect
controlDestination Pitch **Sound
pitch is set relative to vehicle speed.
controlSource Speed
envelope Linear
param 0.4
param 0.01
endEffect
*** Distance Volume ***
beginEffect
controlDestination Volume
controlSource Distance
envelope Ramp
param 25
param 150 **Volume
ramp that fades sound from full to zero between 25 and 150m.
param 1
param -1
endEffect
*** Engine Volume ***
beginEffect
controlDestination Volume
controlSource Default
envelope Ramp
param 0
param .2
param 0
param 1
endEffect
*** Engine stop ***
beginEffect
controlDestination Volume
controlSource TimeRelease
envelope Ramp
param 0
param 0.2
param 1
param -1
endEffect
>>Sound played while engine is at high
output.
>>This is a short range sound that only modifies the current
engine sound playing in HiRPM1.
################
### Hi RPM 2 ###
################
load @ROOT/Sound/@RTD/DesertCombat/Humvee/Humvee_High.wav
volume 1
loop **Chosen
.wav will loop forever until terminated
minDistance 2
relativePosition 0/0/0
priority 8 **On a scale of –10
to 10, this sound has a priority of 8 when competing for sound channel
use with other overlapping sounds.
*** Engine start ***
beginEffect
controlDestination Volume
controlSource Time
envelope Ramp
param 0.2
param 0.8
param 0
param 1
endEffect
*** Engine Pitch ***
beginEffect
controlDestination Pitch
controlSource Default
envelope Linear
param 0.75
param 0.25
endEffect
*** Distance Volume ***
beginEffect
controlDestination Volume
controlSource Distance
envelope Ramp
param 25
param 65
param 1
param -1
endEffect
*** Engine Volume ***
beginEffect
controlDestination Volume
controlSource Default
envelope Ramp
param 0
param .5 **Engine
sound is silent at engine idle and fades to full volume when engine output
is at 50%.
param 0
param 1
endEffect
*** Engine stop ***
beginEffect
controlDestination Volume
controlSource TimeRelease
envelope Ramp
param 0
param 0.2
param 1
param -1
endEffect
>>Sound played while engine is idling.
############
### Idle ###
############
load @ROOT/Sound/@RTD/DesertCombat/Humvee/Humvee_Idle.wav
loop
minDistance 2
relativePosition 0/0/0
priority 8
*** Engine start ***
beginEffect
controlDestination Volume
controlSource Time
envelope Ramp
param 0.2
param 0.8
param 0
param 1
endEffect
*** Engine Pitch ***
beginEffect
controlDestination Pitch
controlSource Default
envelope Ramp
param 0
param 0.25
param 1
param 0.2
endEffect
*** Engine Volume ***
beginEffect
controlDestination Volume
controlSource Default
envelope Ramp
param 0
param 0.9
param 1
param -1 **
Idle sound begins at full volume and fades to silence as engine approaches
90% output.
endEffect
*** Distance Volume ***
beginEffect
controlDestination Volume
controlSource Distance
envelope Ramp
param 5
param 50
param 1
param -1
endEffect
*** Engine stop ***
beginEffect
controlDestination Volume
controlSource TimeRelease
envelope Ramp
param 0
param 0.2
param 1
param -1
endEffect
>>Sound played when drivers seat is abandoned.
###################
### Engine Stop ###
###################
load @ROOT/Sound/@RTD/DesertCombat/Humvee/Humvee_Stop.wav
minDistance 2
trigger Release
**Sound waits to be played until the
vehicle is “released”
dopplerOff
priority -2
*** Distance Volume ***
beginEffect
controlDestination Volume
controlSource Distance
envelope Ramp
param 50
param 100
param 1
param -1
endEffect
Soundscript Titles
Consider the following code:
###################
### Engine Stop ###
###################
load @ROOT/Sound/@RTD/DesertCombat/Humvee/Humvee_Stop.wav
minDistance 2
The area set in ### is a soundscript title. They are
used throughout the soundscript to identify the sections both to the scripter
and to the engine itself.
My suggestion is to start with a soundscript from the original BF1942
files and work from there. Use only titles defined in those soundscripts.
As we will see later, there is a way to add comments to your soundscripts,
which will never interfere with the flow or function of the script. So
in my experience it is best to consider soundscript titles a necessary
evil. Just use them as they appear in the original files and use your
own comments to label the sections as you need.
Soundscript structure
As you can see from the example soundscript above, there is a specific
structure that is usually adhered to. A soundscript section will always
be initiated by the declaration of a sound, using the load command. If
it is an entirely new section, the command newPatch preceeds the load
command. Then, sound parameters follow, such as the declaration of loops,
stereo, and volume properties. Finally, adjustment ramps are declared,
which modify the sound further in accordance to the behavior of the vehicle.
Here is an example layout of a soundscript section:
- NewPatch
- Load the .wav using the proper path
- Declarations section. Define the priority, master volume, looping, stereo,
etc.
- Adjustment ramps. Apply adjustments to pitch and volume according to
time, vehicle speed, engine rpms, distance, etc.
You will notice in the example soundscript provided at the beginning,
that there can be several sounds loaded under one newPatch command. Keep
in mind that newPatch is used to speak to the soundscript interpreter,
and defines the functional sections of the soundscript. It separates out
a reload section from a firing section, for instance.
Loading a sound also has a functional action, and all commands that follow
the loading of a sound are applied to that sound only. Remember that newPatch
separates different functional sections within a soundscript, so you may
load several sounds within a newPatch section. There is no known limit
to the number of sounds you may load for each section.
There is no set rule as to where commands such as stereo, loop, mindistance,
etc. must be stated following the load command. For organization’s
sake, they are usually all declared immediately following the use of the
load command.
As a final note, the location of soundscript sections, separated by newPatch
commands, does not seem to be pre-ordained. You should have freedom over
placement of the primary soundscript sections. However, it is usually
wise to copycat original BF1942 soundscript structure.
Soundscript commands
newPatch Using
this command alerts the script interpreter that a new sound section has
begun. Use of this command is more important for some sounds than others.
For some soundscripts, using many newPatch commands to separate out sections
is essential. For others, there is only a need for one of these commands.
You need not declare a newPatch for every sound that you load. If you
want sounds to be played simultaneously or sequentially, you will usually
group them together under one newPatch. The command newPatch is only used
to communicate with the interpreter, so it may recognize different sections
of the soundscript.
load <path>:
The load command calls forth a sound to be played
from a given path. Once a sound is loaded, all code that follows will
affect that sound, until another load command is issued. The load command
can use relative pathnames to automatically pick from a certain path.
Here are some examples:
@Root:The
root directory of the current mod
@RTD: The
sound quality chosen by the player
@Language: The
language chosen by the player
stereo: If
the sound you are going to use is in stereo, you must alert the script
of this. Use of stereo sounds negates any directional quality of the sound.
If you are in range to hear it, the sound will always sound as though
it occurred at your position.
minDistance <#>:
Mindistance is a greatly speculated upon and misunderstood
command. In my experience, mindistance is the distance at which the sound
begins to naturally lose volume. If you use no volume commands on your
sound, the game will still cause it to lose volume over distance. Setting
a high mindistance increases the radius at which the sound will maintain
high volume on its own.
dopplerOff: Doppler
is the raising / lowering of pitch according to the speed at which an
object is approaching / departing. The engine assumes that doppler is
active unless you deactivate it through use of this command.
priority <#>: Depending
on your sound card, you can only have 32-64 sounds playing at one time.
In the middle of a firefight there are definitely more sounds being called
for than the sound card can handle. Therefore priorities must be set as
to which sounds will be heard while others are not. All overlapping sounds
are in constant competition for being heard. You assign every sound a
priority number ranging from –10 to 10, 10 being highest. There
is a priority 11 but that is reserved only for radio commands. Good decisions
made on sound priorities are essential for an effective sound environment.
loop: If you want your sound to be played on an infinite loop, you will
want to add this command. You can still control the audibility of the
sound using other commands and especially with volume ramps and time delays.
There is no command to loop a sound a selected number of times. However,
with smart use of time / volume parameters you can still have good control
over how a sound is played.
relativePosition <x/y/z>: You
can define where on the vehicle the sound will originate from. The format
of the position is x/y/z (left/right, above/below, forwards/backwards).
Care must be taken in the positioning of the sound, as a soundscript is
often called from a specific component of the vehicle and not the vehicle
itself. For example, a jet engine soundscript is called from the engine,
and therefore a position of 0/0/0 will place the sound origin on the center
of the engine object.
volume <#>:
You may set the sound’s
master volume peak directly using this command. The volume value ranges
from zero (silent) to one (full volume). All further volume adjustments
to the sound will be made relative to the master volume adjustment. So,
for example, if a sound’s master volume is set to 0.5, and then
is later modified to fade to 0.5 volume in a volume ramp, the end volume
will be 0.25.
randomStartPitch<min/max>: With
this command, you may set the sound to be played at a randomly selected
pitch every time it is used. The first parameter is the minimum pitch
value, the second is the maximum pitch value. It is difficult to explain
the mathematics of the pitch parameters, as each follows its own set of
rules. But as an example: randomStartPitch 0.75 / 0.25 sets a pitch range
from 0.75 of the normal pitch to 1.25 of the normal pitch. The first is
a raw factor to be multiplied, the second is to be added to 1 and then
multiplied.
stop finishSample: This
command is only used in conjunction with looping sounds. It tells the
sound to play through the .wav completely before ending, even if the sound
source ceases its activity. This is commonly used in automatic firearms
so that quick taps of the trigger do not cause “half-shots”
to be heard.
randomPlay: This
command requires the use of newPatch and at least two loaded sounds. It
allows the section to randomly pick between all sounds within.
triggerVolume: This
command is only used in conjunction with a time-volume ramp. It prevents
a sound from being played immediately upon the execution of a soundscript.
Instead, the sound is begun at the defined moment the time-volume ramp
is set to raise its volume above zero. If you did not use the triggerVolume
command in a time-volume ramp, the sound would begin the moment the soundscript
is run, regardless of when it is meant to be played. You would end up
with the sound volume being raised from zero in the middle of a playing
sound, which in most cases is undesirable.
#include: This
command is used to load another soundscript, which is run in parallel
with the current script. It’s a great way to save time and effort
when multiple soundscripts will be expected to contain identical sections.
It also allows for the execution of special soundscript commands that
do not work well together. Here is an example of the #include command
used for ejected shell cases:
####################
### Shell Bounce ###
####################
newPatch
#include ../../../Common/Sounds/ShellBounce.ssc
***: Use three subsequent asterisks to begin a comment. These are ignored
by the interpreter and are a great way to organize your soundscripts.
Ramps:
Ramps are methods of controlling a sound’s
properties in accordance to a specified control entity. You can adjust
a sound’s pitch according to the speed of the vehicle, for instance.
Or adjust a sound’s volume according to the observer’s distance.
Some ramp controls are set and unchanging. Others are dynamic and vary
according to vehicle performance or other conditions.
A ramp definition consists of a parameter definition and a parameter set.
Consider the following code excerpt:
*** Start Distance Volume ***
beginEffect
controlDestination Volume
controlSource Distance
envelope Ramp
param 50
param 100
param 0
param 1
endEffect
- Parameter definition: In this area, you specify the source of control
and the method of sound adjustment according to that control. In this
excerpt you can see the source of control is Distance, which is the method
of adjustment for the destination Volume. So as distance changes, volume
changes accordingly. Below this section is the parameter set, which defines
two points where the control source and control destination coincide.
An adjustment ramp is then created using these points as a reference.
- Parameter set: In this area, you specify two points at which you will
define the exact values for the control source and control destination.
The order of the parameters is:
Param1 : control source point 1
Param2 : control source point 2
Param3 : control destination point 1
Param4 : control destination point 2
So verbally, the code excerpt is saying: at 50m the sound volume is zero,
at 100m the sound volume is 1 (full volume).
Using this information, the soundscript creates an adjustment ramp to
modify the sound according to its parameters. For points outside of the
parameter set, the points assume the last stated value in the parameter
set. In other words, the angle of the ramp does not continue beyond the
defined start and end points, but rather maintains the same value as the
end points. So, in this example, an observer closer than 50m to the sound
origin will experience a zero volume level, and an observer beyond 100m
will experience a full volume level. The ramp angle does not continue,
but rather remains level according to the last stated value in the parameter
set.
Now consider the next set of code which immediately follows the above
code:
*** Distance Volume ***
beginEffect
controlDestination Volume
controlSource Distance
envelope Ramp
param 200
param 300
param 1
param -1
endEffect
This ramp continues full folume out to 200m. Then, the volume diminishes
to zero at 300m. Note the use of –1 instead of zero to end the sound.
This is called terminating the sound. It tells the sound engine that no
sound will occur outside of the designated range. This is different than
telling the engine that volume is zero beyond the designated range. Without
terminating the sound, it will continue to infinity and occupy sound channels
throughout the map.
IMPORTANT NOTE: You must terminate all
sounds. Failure to do this will result in loss of available sound channels
across the map. If enough active sounds are not given termination commands,
you will experience massive loss of sound channels in-game.
Here is a description of the many sound ramps that
occur in BF1942. This is just a sampling of the more common ramp codes.
Others may exist and it seems that many in-game variables may be used
to control a ramp.
Time delay:
*** Time Volume ***
beginEffect
controlDestination Volume
controlSource Time
envelope Ramp
param 0.77
param 0.77
param 0
param 1
endEffect
trigger Volume
This ramp is used when a sound should not be played until a designated
amount of time has passed. In this example, the sound will be played 0.77
seconds after the sound triggering event has occurred.
Note the use of trigger Volume immediately after the ramp. This command
is used in conjunction with time delay ramps. It forces the sound to start
when the given time has passed, instead of letting the sound start immediately.
If this ramp was missing the trigger Volume command, you would not hear
the sound from the beginning, but rather from the 0.77 second mark of
the .wav. This command will almost always be used in a time delay ramp.
Engine activity volume ramp:
*** Engine Volume ***
beginEffect
controlDestination Volume
controlSource Default
envelope Ramp
param 0
param 0.75
param 0.25
param 1
endEffect
This ramp is used when a sound should be louder / quieter according to
a vehicle’s engine performance. Many vehicle soundscripts use an
array of sounds with such volume ramps, each sound crossfading with another
as the engine power picks up.
Note the controlSource is listed as Default. While there is no absolute
documentation on the exact meaning of Default, it seems to be a combination
of engine RPM and vehicle speed. The range is from 0 (an idle vehicle)
to 1 (a vehicle at maximum power and speed).
This specific ramp tells the sound to play at 25% when the vehicle is
stopped, and increase to full volume when the vehicle engine reaches 75%
of it’s full power.
Engine RPM pitch ramp:
*** Engine Pitch ***
beginEffect
controlDestination Pitch
controlSource Extern #map<Engine::Rpm>
envelope Ramp
param .2
param .6
param 0.70
param 0.30
endEffect
This ramp is used primarily for aircraft to increase
/ decrease a sound’s pitch according to engine RPM. This ramp is
commonly used to adjust an aircraft engine’s pitch as the pilot
increases throttle.
Note the controlSource is listed as Extern #map<Engine::Rpm>. This
control source is a variable taken directly from the vehicle’s engine
properties. It ranges from 0 (at zero throttle) to 1 (full throttle).
Pitch ramps have parameters that are a bit difficult to interpret. The
two parameters are offsets from the standard value of 1 (which is normal
pitch). It is best to think of the pitch parameters graphically, as they
make little sense mathematically. Let me demonstrate:
This particular ramp is set to param3: 0.7 and param4: 0.3. This means
that when the vehicle is at .2 throttle, the pitch will be at 70% of normal.
When the vehicle is at .6 throttle, the pitch will be at 130% of normal.
Parameter 3 is the actual multiplier of the pitch when the control source
is at parameter 1. Parameter 4 is the multiplier above normal pitch when
the control source is at parameter 2. So you would consider a parameter
4 value of 0.3 to mean the pitch is multiplied by 1.3.
Soundscript tips
Here are some important soundscripting tips to
bear in mind.
- All soundscript commands are CASE SENSITIVE! Never forget this. Sound
paths need not be in the proper case. Everything else in your soundscript
must be properly capitalized.
- Priority is god in soundscripting. Reserve high priorities for sounds
that should always be heard over others. Do not let distant sounds have
high priorities. Break up a sound into several different priorities according
to distance.
- As mentioned before, always terminate your sounds. Doublecheck your
soundscript for termination errors before deeming it complete.
- Stereo sounds have their use, but they are of limited worthiness. The
best time to use a stereo sound is when you want to ensure a sound is
always centered on the player’s ears. They are used for 1st person
view in many weapons for this reason, to disregard slight variance in
positioning. Don’t forget that a stereo sound is twice the file
size as a mono. Use them sparingly.
- If two of the same sound overlap, they will cause a phaser effect that
is usually unwanted. Keep in mind all the sound radii for each .wav, and
try to avoid overlapping the same .wav. For some vehicles, the phaser
effect is desirable. Multiple propeller planes fall into this category.
- Remember that mindistance has its own inherit volume / distance ramp
that you have no control over. If your sound is too quiet at a distance,
even if your volume ramp is not set to reduce volume, consider increasing
the mindistance value.
- A soundscripter is always dependant on the coder to include his soundscripts
in the object he is preparing his scripts for. Work with the coder to
determine what components of a vehicle need a soundscript attached to
them.
- Be wary of multiple engined vehicles if you only want a single soundscript
to handle the engine sound. The coder must ensure only one soundscript
is called for.
- If you want a sound to follow a projectile, you will call for a soundscript
in the projectile’s physics.con file. Looping sounds behave better
for projectiles. Even if a sound is long and will not loop properly, still
set it to loop. Otherwise the soundscript distance properties will only
be calculated once and not be updated as the projectile moves. If a sound
does not loop well and you want to deactivate it as soon as it reaches
the end of the .wav, use a time / volume ramp to terminate it.
- For vehicle engines, consider using a single engine sound set for a
broad pitch range depending on the engine power. Then overlay several
smaller looping sounds that activate at different RPM levels. You can
conserve considerable file size by using this method. Reserve a unique
sound for engine idle.
|