HOW TO ADD
A NEW SOUNDSCRIPTS INTO BATTLEFIELD: 1942
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.
|