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.
|
Go to Step by Step Tools, Step by Step Scripting, Advanced Step by Step Scripting, or Video Tutorials |