Soundscripts: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (Updated file paths and inline code to modern wikitext templates)
(Removed redundant headlines "File format", "Sound entry". Re-organozed headline levels. Used table for Channels. Used class=wikitable for all tables. Added/hid examples for Operator Stacks. Joined two columns of the Sound Characters table. Hid soundscape example by default. {{code}} -> <code>.)
Line 2: Line 2:


{{toc-right}}
{{toc-right}}
'''Soundscripts''' contain "sound entries" that are used to wrap {{src|4}}-specific playback instructions around [[WAV]] or [[MP3]] files.
'''Soundscripts''' contain ''sound entries'' or ''game sounds'' that are used to wrap {{src|4}}-specific playback instructions around [[WAV]] or [[MP3]] files. A ''sound entry'' or ''game sound'' can define the meaning of a sound to NPCs, its pitch and volume, how far away it can be heard from (attenuation), and can be used to randomize which precise sound file is played. [[#Operator stacks|Operator stacks]] {{portal2|since}} can be used to define even more complex behaviors.
 
== File format ==
=== Sound entry ===
 
A sound entry can define the meaning of a sound to NPCs, its pitch and volume, how far away it can be heard from (attenuation), and can be used to randomise which precise sound file is played. [[#Operator stacks|Operator stacks]] {{portal2|since}} can be used to define even more complex behaviours.


Soundscripts are loaded ''on the server only'' from:
Soundscripts are loaded ''on the server only'' from:
Line 15: Line 10:
All filepaths within a soundscript are relative to the game's {{path|sound\}} folder.
All filepaths within a soundscript are relative to the game's {{path|sound\}} folder.


====Example====
<code>'''playgamesound''' <entry></code> is a console command that one can "browse" and play the available ''sound entries'' of a game with.
{{pre|
 
== Example ==
<pre>
entry.name
entry.name
{
{
Line 25: Line 22:
     wave      common/null.wav
     wave      common/null.wav
}
}
}}
</pre>
If a value has a space or tab character within it, wrap it in "quote marks".
If a value has a space or tab character within it, it ''must'' be wrapped in "quote marks".
{{tip|To have a random numeric value chosen every time the sound plays, type a lower bound and a higher bound, separated by a comma. Example: {{code|volume 0.45,0.65}}.}}
 
== Commands ==
 
=== Wave / Rndwave ===


===Commands===
Filename of the sound to play. All file paths can be preceeded with one or two sound characters, see [[#Sound characters|below]].
====Wave / rndwave====
<pre>
Filename of the sound to play.
{{pre|
wave common/blah1.wav
wave common/blah1.wav
}}
</pre>
You can also have the engine pick from a list of random files. A given sound won't repeat until all of the others have played. Note that the random choice is decided by the server, not the client.
You can also have the engine pick from a list of random files. A given sound won't repeat until all of the others have played. Note that the random choice is decided by the server, not the client.
{{pre|
<pre>
rndwave
rndwave
{
{
Line 43: Line 41:
     wave common/blah3.wav
     wave common/blah3.wav
}
}
}}
</pre>
{{note|The sound file MUST be in a folder within the {{path|sound\}} folder. So {{path|sound\folder\sound|wav}} will work, while {{path|sound\sound|wav}} will not.}}
{{note|The sound file MUST be in a folder within the {{path|sound\}} folder. So {{path|sound\folder\sound|wav}} will work, while {{path|sound\sound|wav}} will not.}}


===Volume===
=== Volume ===
A number between 0 and 1, where 1 is the sound's original volume. {{code|VOL_NORM}} will insert your mod's default volume, which will probably be {{code|1}}.
 
A number between 0 and 1, where 1 is the sound's original volume. <code>VOL_NORM</code> will insert your mod's default volume, which will probably be <code>1</code>.
 
To have a random numeric value chosen every time the sound plays, type a lower bound and a higher bound, separated by a comma. Example: <code>volume 0.4,0.6</code>.
 
=== Pitch ===


====Pitch====
Any number between 0 and 255, where 100 is the sound's original pitch and 255 is very high.
Any number between 0 and 255, where 100 is the sound's original pitch and 255 is very high.


*PITCH_LOW = 95
*<code>PITCH_LOW = 95</code>
*PITCH_HIGH = 120
*<code>PITCH_NORM = 100</code>
*<code>PITCH_HIGH = 120</code>
 
To have a random numeric value chosen every time the sound plays, type a lower bound and a higher bound, separated by a comma. Example: <code>pitch 90,110</code>.
 
=== Channel ===


====Channel====
Channels are used to categorize sounds in a way that NPCs, and game logic in general, can understand.
Channels are used to categorize sounds in a way that NPCs, and game logic in general, can understand.
{{confirm|There is a limit of 256 channels total: 224 Static, 32 Dynamic that can play at any given time.}}  
{{confirm|There is a limit of 256 channels total: 224 Static, 32 Dynamic that can play at any given time.}}  
:: '' Exceeding this will result in a channel allocation error, preventing sounds from playing. ''
:: '' Exceeding this will result in a channel allocation error, preventing sounds from playing. ''


;CHAN_AUTO
{| class=wikitable
:Default, generic channel.
! Value for <code>channel</code>
;CHAN_WEAPON
! Description
:Player and NPC weapons.
|-
;CHAN_VOICE
| <code>CHAN_AUTO</code>
:Voiceover dialogue. Used for regular voice lines, etc.
| Default, generic channel.
:{{note|If sound with this channel is emit by an entity that has the "mouth" [[$attachment|attachment]], the sound comes from it.}}
|-
;CHAN_VOICE2
| <code>CHAN_WEAPON</code>
:Additional voice channel. Used in {{tf2}} for the announcer.
| Player and NPC weapons.
;CHAN_ITEM
|-
:Generic physics impact sounds, health/suit chargers, {{Command|+use}} sounds.
| <code>CHAN_VOICE</code>
;CHAN_BODY
| Voiceover dialogue. Used for regular voice lines, etc. {{note|If sound with this channel is emit by an entity that has the "mouth" [[$attachment|attachment]], the sound comes from it.}}
:Clothing, ragdoll impacts, footsteps, knocking/pounding/punching etc.
|-
;CHAN_STREAM
| <code>CHAN_VOICE2</code>
:Sounds that can be delayed by an async load, i.e. aren't responses to particular events.{{confirm|This won't make the sound actually stream; use the * prefix for that.}}
| Additional voice channel. Used in {{tf2}} for the announcer.
;CHAN_REPLACE
|-
:Used when playing sounds through console commands.
| <code>CHAN_ITEM</code>
;CHAN_STATIC
| Generic physics impact sounds, health/suit chargers, {{Command|+use}} sounds.
:A constant/background sound that doesn't require any reaction.
|-
;CHAN_VOICE_BASE
| <code>CHAN_BODY</code>
:Network voice data (online voice communications)
| Clothing, ragdoll impacts, footsteps, knocking/pounding/punching etc.
;CHAN_USER_BASE+<number>
|-
:Custom channels can be defined here (Allocates a channel for the desire sound entry).
| <code>CHAN_STREAM</code>
| Sounds that can be delayed by an ''async'' load, i.e. aren't responses to particular events. {{confirm|This won't make the sound actually stream; use the <code>*</code> path prefix for that, see [[#Sound characters|below]].}}
|-
| <code>CHAN_REPLACE</code>
| Used when playing sounds through console commands.
|-
| <code>CHAN_STATIC</code>
| A constant/background sound that doesn't require any reaction.
|-
| <code>CHAN_VOICE_BASE</code>
| Network voice data (online voice communications)
|-
| <code>CHAN_USER_BASE+<number></code>
| Custom channels can be defined here. Allocates a channel for the desired sound entry.
|}
 
=== Soundlevel ===


====SoundLevel====
The sound's [[w:Attenuation|attenuation]]; how fast it drops away. The engine starts running into trouble below 60dB.
The sound's [[w:Attenuation|attenuation]]; how fast it drops away. The engine starts running into trouble below 60dB.


Line 91: Line 112:
It is possible to pass a literal number value ("150" as opposed to "SNDLVL_150") and freely choose any number between 0 and 255. Games tested: {{hl2|5}} {{hl2ep1|5}} {{hl2ep2|5}} {{p2|5}}
It is possible to pass a literal number value ("150" as opposed to "SNDLVL_150") and freely choose any number between 0 and 255. Games tested: {{hl2|5}} {{hl2ep1|5}} {{hl2ep2|5}} {{p2|5}}


{| class=standard-table
{| class=wikitable
!width=180|Code
! Value for <code>soundlevel</code>
!width=30|Attenuation Value
! Attenuation<br>Value
!width=350|Real World
!width=350| Real World
!width=700|In Game
!width=700| In Game
|-
|-
| '''SNDLVL_NONE'''
| <code><span style=color:white>SNDLVL_NONE</span></code>
| align="middle" | 0
| align="middle" | 0
| Everywhere
| Everywhere
| {{l4d2}}: Music disconnected from environment (Ex: checkpoint music, credit music, mob music)
| {{l4d2}}: Music disconnected from environment (Ex: checkpoint music, credit music, mob music)
|-
|-
| SNDLVL_20dB
| <code>SNDLVL_20dB</code>
|
|
| Rustling leaves
| Rustling leaves
|
|
|-
|-
| SNDLVL_25dB
| <code>SNDLVL_25dB</code>
|
|
| Whispering
| Whispering
|
|
|-
|-
| SNDLVL_30dB
| <code>SNDLVL_30dB</code>
|
|
|  Library, dishwasher
|  Library, dishwasher
|
|
|-
|-
| SNDLVL_35dB
| <code>SNDLVL_35dB</code>
|
|
|
|
|
|
|-
|-
| SNDLVL_40dB
| <code>SNDLVL_40dB</code>
|
|
| Moderate rainfall
| Moderate rainfall
|
|
|-
|-
| SNDLVL_45dB
| <code>SNDLVL_45dB</code>
|
|
| Refrigerator
| Refrigerator
|
|
|-
|-
| SNDLVL_50dB
| <code>SNDLVL_50dB</code>
| align="middle" | 3.9
| align="middle" | 3.9
| Average home, heavy rainfall
| Average home, heavy rainfall
|
|
|-
|-
| SNDLVL_55dB
| <code>SNDLVL_55dB</code>
| align="middle" | 3.0
| align="middle" | 3.0
|
|
| {{l4d2}}: Digital alarm clock in C8M1_Apartment.
| {{l4d2}}: Digital alarm clock in C8M1_Apartment.
|-
|-
| SNDLVL_60dB<br>'''SNDLVL_IDLE'''
| <code>SNDLVL_60dB</code><br><code><span style=color:white>SNDLVL_IDLE</span></code>
| align="middle" | 2.0  
| align="middle" | 2.0  
| Normal conversation, clothes dryer
| Normal conversation, clothes dryer
|
|
|-
|-
| SNDLVL_65dB
| <code>SNDLVL_65dB</code>
| align="middle" | 1.5
| align="middle" | 1.5
| Washing machine, dishwasher
| Washing machine, dishwasher
|
|
|-
|-
| '''SNDLVL_STATIC'''
| <code><span style=color:white>SNDLVL_STATIC</span></code>
| align="middle" | 1.25
| align="middle" | 1.25
|
|
|
|
|-
|-
| SNDLVL_70dB
| <code>SNDLVL_70dB</code>
| align="middle" | 1.0
| align="middle" | 1.0
| Car, vacuum cleaner, mixer, electric sewing machine
| Car, vacuum cleaner, mixer, electric sewing machine
| {{l4d2}}: Moustachio whack smash and pop-up, tv static, whacked piano
| {{l4d2}}: Moustachio whack smash and pop-up, tv static, whacked piano
|-
|-
| SNDLVL_75dB<br>'''SNDLVL_NORM'''
| <code>SNDLVL_75dB</code><br><code><span style=color:white>SNDLVL_NORM</span></code>
| align="middle" | 0.8
| align="middle" | 0.8
| Busy traffic
| Busy traffic
| {{l4d2}}: Various doors, swarm of flies, Lilpeanut audible, bullet impact on wood.
| {{l4d2}}: Various doors, swarm of flies, Lilpeanut audible, bullet impact on wood.
|-
|-
| SNDLVL_80dB  
| <code>SNDLVL_80dB</code>
|rowspan=2 align="middle" | 0.7
|rowspan=2 align="middle" | 0.7
| Mini-bike, alarm clock, noisy restaurant, office tabulator, outboard motor, passing snowmobile, police siren
| Mini-bike, alarm clock, noisy restaurant, office tabulator, outboard motor, passing snowmobile, police siren
| {{l4d2}}: Jukebox, music spitter spit pile as source.
| {{l4d2}}: Jukebox, music spitter spit pile as source.
|-
|-
| '''SNDLVL_TALKING'''
| <code><span style=color:white>SNDLVL_TALKING</span></code>
|  
|  
| Valve's chosen dialogue attenuation
| Valve's chosen dialogue attenuation
|-
|-
| SNDLVL_85dB
| <code>SNDLVL_85dB</code>
| align="middle" | 0.6
| align="middle" | 0.6
| Average factory, electric shaver
| Average factory, electric shaver
| {{l4d2}}: Moustachio strength attract, big fire after airliner crash in C11M5_runway
| {{l4d2}}: Moustachio strength attract, big fire after airliner crash in C11M5_runway
|-
|-
| SNDLVL_90dB
| <code>SNDLVL_90dB</code>
| align="middle" | 0.5
| align="middle" | 0.5
| Screaming child, passing motorcycle, convertible ride on freeway, hair dryer
| Screaming child, passing motorcycle, convertible ride on freeway, hair dryer
| {{l4d2}}: Moustachio strength attract, gas can bursting
| {{l4d2}}: Moustachio strength attract, gas can bursting
|-
|-
| SNDLVL_95dB
| <code>SNDLVL_95dB</code>
|
|
|
|
|{{l4d2}}: Mounted Machine Gun
|{{l4d2}}: Mounted Machine Gun
|-
|-
| SNDLVL_100dB
| <code>SNDLVL_100dB</code>
| align="middle" | 0.4
| align="middle" | 0.4
| Subway train, diesel truck, woodworking shop, pneumatic drill, boiler shop, jackhammer
| Subway train, diesel truck, woodworking shop, pneumatic drill, boiler shop, jackhammer
| {{l4d2}}: Music coop player in danger AKA tags (ledge hanging, pinned down by SI), Elevators.
| {{l4d2}}: Music coop player in danger AKA tags (ledge hanging, pinned down by SI), Elevators.
|-
|-
| SNDLVL_105dB
| <code>SNDLVL_105dB</code>
|
|
| Helicopter, power mower
| Helicopter, power mower
|
|
|-
|-
| SNDLVL_110dB
| <code>SNDLVL_110dB</code>
|
|
| Snowmobile (drivers seat), inboard motorboat, sandblasting, chainsaw
| Snowmobile (drivers seat), inboard motorboat, sandblasting, chainsaw
| {{l4d2}}: Boomer alert close, Van in C11M4_Terminal.
| {{l4d2}}: Boomer alert close, Van in C11M4_Terminal.
|-
|-
| SNDLVL_120dB
| <code>SNDLVL_120dB</code>
|
|
| Car horn, propeller aircraft, concert
| Car horn, propeller aircraft, concert
| {{l4d2}}: Boomer alert, Indoor fire in C1M1_Hotel, Fireworks in C2M5_Concert, Rain in "Hard Rain" campaign.
| {{l4d2}}: Boomer alert, Indoor fire in C1M1_Hotel, Fireworks in C2M5_Concert, Rain in "Hard Rain" campaign.
|-
|-
| SNDLVL_125dB
| <code>SNDLVL_125dB</code>
|
|
|
|
| {{l4d2}}: Boomer alert far
| {{l4d2}}: Boomer alert far
|-
|-
| SNDLVL_130dB
| <code>SNDLVL_130dB</code>
|
|
| Air raid siren, fireworks
| Air raid siren, fireworks
| {{l4d2}}: Carousel music during crescendo event, C5M2_park perimeter alarm.
| {{l4d2}}: Carousel music during crescendo event, C5M2_park perimeter alarm.
|-
|-
| ''' SNDLVL_GUNFIRE'''
| <code><span style=color:white>SNDLVL_GUNFIRE</span></code>
| align="middle" | 0.27
| align="middle" | 0.27
| Threshold of pain, gunshot, jet engine
| Threshold of pain, gunshot, jet engine
|
|
|-
|-
| SNDLVL_140dB
| <code>SNDLVL_140dB</code>
| align="middle" | 0.2
| align="middle" | 0.2
| Airplane taking off, jackhammer
| Airplane taking off, jackhammer
| {{l4d2}}: Flock of crows, Lowering bridge in C5m5_Bridge, APC engine.
| {{l4d2}}: Flock of crows, Lowering bridge in C5m5_Bridge, APC engine.
|-
|-
| SNDLVL_145dB
| <code>SNDLVL_145dB</code>
|  
|  
|
|
| {{l4d2}}: Wandering witch music ("lost little witch")
| {{l4d2}}: Wandering witch music ("lost little witch")
|-
|-
| SNDLVL_150dB
| <code>SNDLVL_150dB</code>
| align="middle" | 0.2
| align="middle" | 0.2
| Smithing hammer
| Smithing hammer
| {{l4d2}}: Concert music, parade music, zombie choir, Boat Horn
| {{l4d2}}: Concert music, parade music, zombie choir, Boat Horn
|-
|-
| SNDLVL_180dB
| <code style=color:white>SNDLVL_180dB</code>
|
|
| Rocket launching
| Rocket launching
Line 247: Line 268:
|}
|}


===Operator stacks===
== Operator stacks ==
[[Portal 2 engine branch]] introduced [[Sound operators|Operator Stacks]], which are used to add complex behaviour to sounds. To enable them, you must set {{code|soundentry_version}} to {{code|2}}.
 
{{seealso|[[Sound operators]]}}


[[Portal 2 engine branch]] introduced '''Operator Stacks''', which are used to add complex behaviour to sounds.
Outside {{p2|2.bold}}, they are supported in {{csgo|2.bold}} and {{dota2|2.bold}} (which now uses {{src2|1.bold}}; the operator stacks have been greatly expanded upon and many of their names have been changed), {{doi|2.bold}}, and {{insurgency|2.bold}}.
Outside {{p2|2.bold}}, they are supported in {{csgo|2.bold}} and {{dota2|2.bold}} (which now uses {{src2|1.bold}}; the operator stacks have been greatly expanded upon and many of their names have been changed), {{doi|2.bold}}, and {{insurgency|2.bold}}.


There are three types of stack, each triggered at different times:
=== Syntax ===
*{{code|prestart_stack}}
 
*{{code|start_stack}}
To use the <code>operator_stacks</code> keyvalue, a sound entry must contain the key-value pair <code>soundentry_version 2</code>.
*{{code|update_stack}}
 
*{{code|stop_stack}}
There are three types of stacks, each triggered at different times:
*<code>prestart_stack</code> and <code>start_stack</code>, executed once when a sound entry is started,
*<code>update_stack</code>, executed regularly during playback,
*<code>stop_stack</code>, executed once when the entry is stopped.
 
Inside these stacks, one can put one or multiple ''operators'', where the key is an arbitrary operator name and the value once another keyvalues that contains the key-value pair <code>operator <sound_operator_name></code> along with more key-value pairs defining what the operator does, which can be found at [[sound operators]].
 
You can either start from scratch or use the <code>import_stack</code> command to extend a template defined in {{path|scripts\sound_operator_stacks|txt}}.
 
There are [[Sound operators|28 operators]] used in {{portal2|3}}, but they are re-configured and combined in hundreds of different ways. Most of the resulting "stacks" are very specific, and this page will only deal with the more general ones.
 
{{todo|Work out a sane way of documenting all this!}}
 
=== Examples ===
 
{{expand|
Syntax of the <code>operator_stacks</code> keyvalue:
<syntaxhighlight lang=php>
entry.name
{
channel CHAN_STATIC
soundlevel SNDLVL_NONE
volume 1.0
wave "common/null.wav"
 
soundentry_version 2
 
operator_stacks
{
prestart_stack // optional
{
// ...
}
start_stack // optional
{
// ...
}
update_stack // optional
{
// ...
}
end_stack // optional
{
// ...
}
}
}
</syntaxhighlight>
 


In each case you can either start from scratch or use the {{code|import_stack}} command to extend a template defined in {{path|scripts\sound_operator_stacks|txt}}.


====Example====
Example for a <code>start_stack</code> referencing the operators <code>[[Sound operators#math_random|math_random]]</code> and <code>[[Sound operators#sys_output|sys_output]]</code>:
<syntaxhighlight lang=php highlight=14-31>
<syntaxhighlight lang=php>
entry.name
{
// ...
 
operator_stacks
{
start_stack
{
random_number // name is arbitrary
{
operator "math_random" // stores a random number (-3 <= x <= 3) inside "random_number.output"
input_min -3.0
input_max 3.0
}
apply_delay // name is arbitrary
{
operator "sys_output" // applies a delay to the sound (negative delay = skip into the sound)
output delay
input_float @random_number.output // accesses the output of the previous operator "random_number"
}
}
}
}
</syntaxhighlight>
 
 
 
Full sound entry example using <code>import_stack</code>:
<syntaxhighlight lang=php <!--highlight=14-31-->
VFX.LightFlickerEnd  
VFX.LightFlickerEnd  
{
{
Line 269: Line 368:
rndwave
rndwave
{
{
wave "vfx/light_flicker/light_flicker_end_01.wav"
wave "vfx/light_flicker/light_flicker_end_01.wav"
wave "vfx/light_flicker/light_flicker_end_02.wav"
wave "vfx/light_flicker/light_flicker_end_02.wav"
wave "vfx/light_flicker/light_flicker_end_03.wav"
wave "vfx/light_flicker/light_flicker_end_03.wav"
wave "vfx/light_flicker/light_flicker_end_04.wav"
wave "vfx/light_flicker/light_flicker_end_04.wav"
}
}


Line 283: Line 382:
import_stack "P2_exclusion_time_blocker_start" // defined in scripts/sound_operator_stacks.txt
import_stack "P2_exclusion_time_blocker_start" // defined in scripts/sound_operator_stacks.txt


// We are now extending/configuring P2_exclusion_time_blocker_start
// We are now extending/configuring "P2_exclusion_time_blocker_start"
// which contains an operator with the exact name "block_entries" that we edit now:


block_entries // prevents another sound from playing
block_entries // prevents another sound from playing
{
{
input_duration 0.25 // seconds to block for
input_duration 0.25 // seconds to block for
match_entry "World.LightFlickerEnd" // the sound entry to block
match_entry "World.LightFlickerEnd" // the sound entry to block
match_entity false // only on the same entity that this sound is playing from?
match_entity false // only on the same entity that this sound is playing from?
}
}
}
}
Line 296: Line 396:
</syntaxhighlight>
</syntaxhighlight>


====Templates====
There are [[Sound operators|28 operators]] used in {{portal2|3}}, but they are re-configured and combined in hundreds of different ways. Most of the resulting "stacks" are very specific, and this page will only deal with the more general ones.


{{todo|Work out a sane way of documenting all this!}}


=====limit_sound=====
Limits the maximum number of sounds that can be played at once, either by sound name or entity. A sound will not stop itself from playing.
Limits the maximum number of sounds that can be played at once, either by sound name or entity. A sound will not stop itself from playing.
<syntaxhighlight lang=php>
<syntaxhighlight lang=php>
import_stack "P2_poly_limiting_start"
import_stack "P2_poly_limiting_start"
Line 314: Line 409:
</syntaxhighlight>
</syntaxhighlight>


=====position_array=====
 
 
Smoothly transitions a sound from one location to up to eight others as the player moves through a map. An unreleased tool can auto-generate these. Position 1 is where the sound was emitted from.
Smoothly transitions a sound from one location to up to eight others as the player moves through a map. An unreleased tool can auto-generate these. Position 1 is where the sound was emitted from.
{{confirm|The tool mentioned above ''may'' be in the files of {{ddd|4}}.}}
{{tip|The tool mentioned above ''may'' be in the files of {{ddd|4}}.}}
 
<syntaxhighlight lang=php>
<syntaxhighlight lang=php>
import_stack "p2_update_dialog_spatial_cave"
import_stack "p2_update_dialog_spatial_cave"
Line 335: Line 430:
</syntaxhighlight>
</syntaxhighlight>


=====play_entry=====
 
 
Plays another sound entry.
Plays another sound entry.
<syntaxhighlight lang=php>
<syntaxhighlight lang=php>
import_stack "stop_and_play"
import_stack "stop_and_play"
Line 346: Line 441:
}
}
</syntaxhighlight>
</syntaxhighlight>
}}
== Sound characters ==


===Sound characters===
The first two characters of a WAV's name are scanned for the following:
The first two characters of a WAV's name are scanned for the following:


{| class=standard-table
{| class=wikitable
! width=30|Symbol
! width=3em| Symbol
! width=180|Name
! Name
! width=350|Purpose
!style=white-space:nowrap| Game/branch
! Game/branch
! Purpose / Notes
! width=700|Notes
|-
|-
| align="middle" | '''*''' || align="middle" | '''CHAR_STREAM''' || Streams from the disc, get flushed soon after. Use for one-off dialogue files or non-looping music. || align="middle" | All ||
| align=middle | <code style=font-size:125%>*</code>
| '''CHAR_STREAM'''
| align=middle | ''all''
| Streams from the disc, get flushed soon after. Use for one-off dialogue files or non-looping music.
|-
|-
| align="middle" | '''#''' || align="middle" | '''CHAR_DRYMIX''' || Bypasses [[DSP]], becomes affected by the user's music volume setting (snd_musicvolume). The latter part also requires the sound to be non directional (soundlevel of 0). || align="middle" | -//- || {{Warning|Using this character on a sound entry utilizing an update_stack where the volume is zeroed out, whether by the update_stack or by the sound entry itself(volume 0.0), will cause an update_stack loop. Not only does this have negative performance implications, the sound will consume an audio channel until the loop is interrupted or the sound is stopped.{{inline note|name=Confirm}}}}
| align=middle | <code style=font-size:125%>#</code>
| '''CHAR_DRYMIX'''
| align=middle | ''all''
| Bypasses [[DSP]], becomes affected by the user's music volume setting ({{ent|snd_musicvolume}}). The latter part also requires the sound to be non directional (soundlevel of 0). {{Warning|Using this character on a sound entry utilizing an ''operator stack'' with an <code>update_stack</code> where the volume is zeroed out, whether by the <code>update_stack</code> or by the sound entry itself (<code>volume 0.0</code>), will cause an <code>update_stack</code> loop. Not only does this have negative performance implications, the sound will consume an audio channel until the loop is interrupted or the sound is stopped. {{inline note|name=Confirm}}}}
|-
|-
| align="middle" | '''@''' || align="middle" | '''CHAR_OMNI''' || Non-directional sound; plays "everywhere", similar to SNDLVL_NONE, except it fades with distance from its source based on its sound level. || align="middle" | -//- ||
| align=middle | <code style=font-size:125%>@</code>
| '''CHAR_OMNI'''
| align=middle | ''all''
| Non-directional sound; plays "everywhere", similar to <code>SNDLVL_NONE</code>, except it fades with distance from its source based on its soundlevel.
|-
|-
| align="middle" | '''>''' || align="middle" | '''CHAR_DOPPLER''' || Doppler encoded stereo: left for heading towards the listener and right for heading away. || align="middle" | -//- ||
| align=middle | <code style=font-size:125%>&gt;</code>
| '''CHAR_DOPPLER'''
| align=middle | ''all''
| Doppler encoded stereo: left for heading towards the listener and right for heading away.
|-
|-
| align="middle" | '''<''' || align="middle" | '''CHAR_DIRECTIONAL''' || Stereo with direction: left channel for front facing, right channel for rear facing. Mixed based on listener's direction. || align="middle" | -//- || {{todo|Relationship with {{code|CHAR_DIRSTEREO}} in {{csgo|2.bold}}?}}
| align=middle | <code style=font-size:125%>&lt;</code>
| '''CHAR_DIRECTIONAL'''
| align=middle | ''all''
| Stereo with direction: left channel for front facing, right channel for rear facing. Mixed based on listener's direction. {{todo|Relationship with <code>CHAR_DIRSTEREO</code> in {{csgo|2.bold}}?}}
|-
|-
| align="middle" | '''^''' || align="middle" | '''CHAR_DISTVARIANT''' || Distance-variant stereo. Left channel is close, right channel is far. || align="middle" | -//- || Transition distance is hard-coded; [[Soundscripts#Distance variance in Source|see below]].
| align=middle | <code style=font-size:125%>^</code>
| '''CHAR_DISTVARIANT'''
| align=middle | ''all''
| Distance-variant stereo. Left channel is close, right channel is far. {{note|Transition distance is hard-coded, see [[#Distance variance in Source|below]].
|-
|-
| align="middle" | ''')''' || align="middle" | '''CHAR_SPATIALSTEREO''' || Spatializes both channels, allowing them to be placed at specific locations within the world; [[Soundscripts#Spatial stereo|see below]]. || align="middle" | -//- || Sometimes {{code|(}} must be used instead; [[Soundscripts#Spatial stereo|see below]].
| align=middle | <code style=font-size:125%>)</code>
| '''CHAR_SPATIALSTEREO'''
| align=middle | ''all''
| Spatializes both channels, allowing them to be placed at specific locations within the world; [[Soundscripts#Spatial stereo|see below]]. {{note|Sometimes <code>(</code> must be used instead, see [[#Spatial stereo|below]].}}
|-
|-
| align="middle" | '''}''' || align="middle" | '''CHAR_FAST_PITCH''' || Forces low quality, non-interpolated pitch shift. || align="middle" | -//- ||
| align=middle | <code style=font-size:125%>}</code>
| '''CHAR_FAST_PITCH'''
| align=middle | ''all''
| Forces low quality, non-interpolated pitch shift.
|-
|-
| align="middle" | '''$''' || align="middle" | '''CHAR_CRITICAL''' || Forces sound to be cached at a fixed point in memory. || align="middle" | Up to {{src06}} || Only affects {{xbox|2.bold}}, which streams all audio regardless of * unless marked as critical. {{src07|removed}}.
| align=middle | <code style=font-size:125%>$</code>
| '''CHAR_CRITICAL'''
| align=middle | Up to {{src06}}
| Forces sound to be cached at a fixed point in memory. {{note|Only affects {{xbox|2.bold}}, which streams all audio regardless of <code>*</code> unless marked as critical. {{src07|removed}}}}
|-
|-
| align="middle" | '''!''' || align="middle" | '''CHAR_SENTENCE''' || An NPC [[sentence]]. || align="middle" | Since {{src09}} ||
| align=middle | <code style=font-size:125%>!</code>
| '''CHAR_SENTENCE'''
| align=middle | Since {{src09}}
| An NPC [[sentence]].
|-
|-
| align="middle" | '''?''' || align="middle" | '''CHAR_USERVOX''' || Voice chat data. You shouldn't ever need to use this. || align="middle" | All ||
| align=middle | <code style=font-size:125%>?</code>
| '''CHAR_USERVOX'''
| align=middle | ''all''
| Voice chat data. You shouldn't ever need to use this.
|-
|-
| align="middle" | '''&''' || align="middle" | '''CHAR_HRTF_FORCE''' || Indicates wav should use HRTF spatialization for all entities (including owners). || align="middle" | {{csgo}} ||
| align=middle | <code style=font-size:125%>&</code>
| '''CHAR_HRTF_FORCE'''
| align=middle | {{csgo}}
| Indicates wav should use HRTF spatialization for all entities (including owners).
|-
|-
| align="middle" | '''~''' || align="middle" | '''CHAR_HRTF''' || Indicates wav should use HRTF spatialization for non-owners. || align="middle" | {{csgo}} ||
| align=middle | <code style=font-size:125%>~</code>
| '''CHAR_HRTF'''
| align=middle | {{csgo}}
| Indicates wav should use HRTF spatialization for non-owners.
|-
|-
| align="middle" | '''`''' || align="middle" | '''CHAR_HRTF_BLEND''' || Indicates wav should use HRTF spatialization for non-owners, blended with stereo for sounds sufficiently close. || align="middle" | {{csgo}} ||
| align=middle | <code style=font-size:125%>`</code>
| '''CHAR_HRTF_BLEND'''
| align=middle | {{csgo}}
| Indicates wav should use HRTF spatialization for non-owners, blended with stereo for sounds sufficiently close.
|-
|-
| align="middle" | '''+''' || align="middle" | '''CHAR_RADIO''' || Indicates a 'radio' sound -- should be played without spatialization. || align="middle" | {{csgo}} ||
| align=middle | <code style=font-size:125%>+</code>
| '''CHAR_RADIO'''
| align=middle | {{csgo}}
| Indicates a 'radio' sound -- should be played without spatialization.
|-
|-
| align="middle" | '''$''' || align="middle" | '''CHAR_SUBTITLED''' || Indicates the subtitles are forced. || align="middle" | {{csgo}} ||
| align=middle | <code style=font-size:125%>$</code>
| '''CHAR_SUBTITLED'''
| align=middle | {{csgo}}
| Indicates the subtitles are forced.
|-
|-
| align="middle" | '''%''' || align="middle" | '''CHAR_MUSIC''' ||Indicates main menu music. || align="middle" | {{csgo}} ||
| align=middle | <code style=font-size:125%>%</code>
| '''CHAR_MUSIC'''
| align=middle | {{csgo}}
| Indicates main menu music.
|-
|-
| align="middle" | '''(''' || align="middle" | '''CHAR_DIRSTEREO''' || Indicates directional stereo wav (like doppler). || align="middle" | {{csgo}} {{l4d2}} ||
| align=middle | <code style=font-size:125%>(</code>
| '''CHAR_DIRSTEREO'''
| align=middle | {{csgo}} {{l4d2}}
| Indicates directional stereo wav (like doppler).
|}
|}


Line 398: Line 548:
*{{path|*@npc/vo/announcer/specialoffer|wav}}
*{{path|*@npc/vo/announcer/specialoffer|wav}}


====Spatial Stereo====
=== Spatial Stereo ===
Adding {{code|)}} in front of a stereo sound name in the soundscript such as {{path|)weapons/m4a1/m4_shoot|wav}} tells the sound engine that it is a ''spatialized'' sound; this allows the sound to emit from a specific location within the world. When not used, stereo sounds play in a fixed 2-channel orientation and cannot be panned to simulate a location. Single-channel files do not require {{code|)}} before the filename and will be ''spatialized'' automatically.
Adding <code>)</code> in front of a stereo sound name in the soundscript such as {{path|)weapons/m4a1/m4_shoot|wav}} tells the sound engine that it is a ''spatialized'' sound; this allows the sound to emit from a specific location within the world. When not used, stereo sounds play in a fixed 2-channel orientation and cannot be panned to simulate a location. Single-channel files do not require <code>)</code> before the filename and will be ''spatialized'' automatically.


=====Soundscapes=====
=== Soundscapes ===
[[Soundscape]]s have special needs. Stereo wave files used in {{code|PlayRandom}} require that {{code|(}} is placed before the filename. {{code|PlayLooping}} still uses {{code|)}} but {{code|(}} will spatialize the two channels separately for an alternate effect; {{code|(}} sounds more environmental, but the exact nature of this behavior is unknown. Generic soundscripts can sometimes use {{code|(}} to gain the same stereo spatialization that occurs in {{code|PlayLooping}}.
[[Soundscape]]s have special needs. Stereo wave files used in <code>PlayRandom</code> require that <code>(</code> is placed before the filename. <code>PlayLooping</code> still uses <code>)</code> but <code>(</code> will spatialize the two channels separately for an alternate effect; <code>(</code> sounds more environmental, but the exact nature of this behavior is unknown. Generic soundscripts can sometimes use <code>(</code> to gain the same stereo spatialization that occurs in <code>PlayLooping</code>.


{{Confirm|Is this {{code|(}} stereo-spatialization behavior present in all engine branches? Some preliminary testing reveals it may be absent from {{gmod|4}}.}}
{{Confirm|Is this <code>(</code> stereo-spatialization behavior present in all engine branches? Some preliminary testing reveals it may be absent from {{gmod|4}}.}}
 
For example:


{{expand|title=Example
|
<syntaxhighlight lang=php>
<syntaxhighlight lang=php>
wave ")ambient/stereo_alarm.wav" // Typical usage in a standard soundscript
wave ")ambient/stereo_alarm.wav" // Typical usage in a standard soundscript
Line 440: Line 590:
}
}
</syntaxhighlight>
</syntaxhighlight>
}}


====Distance variance in Source====
=== Distance variance in Source ===
Adding {{code|^}} in front of a sound name, such as {{path|^weapons/explode3|wav}} tells the sound engine that it is a distance based sound. The left channel of the sound file is the 'near' sound that will play when the sound originates close to you, and the right channel is the 'far' sound that will play when the sound originates far from you. If the {{code|^}} mark is not used in the soundscript, the sound is treated as stereo with no directionality or distance. This is a different feature than the {{code|sndlvl}} entry to control attenuation. This distant variant feature allows you to play two different sounds (but using only one file) and crossfading between the two depending on how far away the sound originates.
Adding <code>^</code> in front of a sound name, such as {{path|^weapons/explode3|wav}} tells the sound engine that it is a distance based sound. The left channel of the sound file is the 'near' sound that will play when the sound originates close to you, and the right channel is the 'far' sound that will play when the sound originates far from you. If the <code>^</code> mark is not used in the soundscript, the sound is treated as stereo with no directionality or distance. This is a different feature than the <code>soundlevel</code> property to control attenuation. This distant variant feature allows you to play ''two different sounds'' (but using only one file) and crossfading between the two depending on how far away the sound originates.


The fade distances are hardcoded to begin at 240 world units and end at 1320 world units, and cannot be changed in custom maps or mods.
The fade distances are hardcoded to begin at 240 world units and end at 1320 world units, and cannot be changed in custom maps or mods.


==See also==
== See also ==
*{{ent|ambient_generic}}
*{{ent|ambient_generic}}
*[[Soundscape]]
*[[Soundscape]]

Revision as of 03:45, 25 December 2024

English (en)Translate (Translate)

Soundscripts contain sound entries or game sounds that are used to wrap Source Source-specific playback instructions around WAV or MP3 files. A sound entry or game sound can define the meaning of a sound to NPCs, its pitch and volume, how far away it can be heard from (attenuation), and can be used to randomize which precise sound file is played. Operator stacks (in all games since Portal 2) can be used to define even more complex behaviors.

Soundscripts are loaded on the server only from:

  • 🖿scripts\game_sounds_manifest.txt
  • 🖿maps\<mapname>_level_sounds.txt (not in Counter-Strike: Global Offensive)

All filepaths within a soundscript are relative to the game's 🖿sound\ folder.

playgamesound <entry> is a console command that one can "browse" and play the available sound entries of a game with.

Example

entry.name
{
    channel    CHAN_AUTO
    volume     VOL_NORM
    pitch      PITCH_NORM
    soundlevel SNDLVL_NORM
    wave       common/null.wav
}

If a value has a space or tab character within it, it must be wrapped in "quote marks".

Commands

Wave / Rndwave

Filename of the sound to play. All file paths can be preceeded with one or two sound characters, see below.

wave common/blah1.wav

You can also have the engine pick from a list of random files. A given sound won't repeat until all of the others have played. Note that the random choice is decided by the server, not the client.

rndwave
{
    wave common/blah1.wav
    wave common/blah2.wav
    wave common/blah3.wav
}
Note.pngNote:The sound file MUST be in a folder within the 🖿sound\ folder. So 🖿sound\folder\sound.wav will work, while 🖿sound\sound.wav will not.

Volume

A number between 0 and 1, where 1 is the sound's original volume. VOL_NORM will insert your mod's default volume, which will probably be 1.

To have a random numeric value chosen every time the sound plays, type a lower bound and a higher bound, separated by a comma. Example: volume 0.4,0.6.

Pitch

Any number between 0 and 255, where 100 is the sound's original pitch and 255 is very high.

  • PITCH_LOW = 95
  • PITCH_NORM = 100
  • PITCH_HIGH = 120

To have a random numeric value chosen every time the sound plays, type a lower bound and a higher bound, separated by a comma. Example: pitch 90,110.

Channel

Channels are used to categorize sounds in a way that NPCs, and game logic in general, can understand.

Confirm:There is a limit of 256 channels total: 224 Static, 32 Dynamic that can play at any given time.
Exceeding this will result in a channel allocation error, preventing sounds from playing.
Value for channel Description
CHAN_AUTO Default, generic channel.
CHAN_WEAPON Player and NPC weapons.
CHAN_VOICE Voiceover dialogue. Used for regular voice lines, etc.
Note.pngNote:If sound with this channel is emit by an entity that has the "mouth" attachment, the sound comes from it.
CHAN_VOICE2 Additional voice channel. Used in Team Fortress 2 for the announcer.
CHAN_ITEM Generic physics impact sounds, health/suit chargers, +use sounds.
CHAN_BODY Clothing, ragdoll impacts, footsteps, knocking/pounding/punching etc.
CHAN_STREAM Sounds that can be delayed by an async load, i.e. aren't responses to particular events.
Confirm:This won't make the sound actually stream; use the * path prefix for that, see below.
CHAN_REPLACE Used when playing sounds through console commands.
CHAN_STATIC A constant/background sound that doesn't require any reaction.
CHAN_VOICE_BASE Network voice data (online voice communications)
CHAN_USER_BASE+<number> Custom channels can be defined here. Allocates a channel for the desired sound entry.

Soundlevel

The sound's attenuation; how fast it drops away. The engine starts running into trouble below 60dB.

The following list contains all default sound levels, their attenuation value, real world examples, and in-game examples. All values and real world examples were taken from 🖿src\public\soundflags.h.

It is possible to pass a literal number value ("150" as opposed to "SNDLVL_150") and freely choose any number between 0 and 255. Games tested: Half-Life 2 Half-Life 2: Episode One Half-Life 2: Episode Two Portal 2

Value for soundlevel Attenuation
Value
Real World In Game
SNDLVL_NONE 0 Everywhere Left 4 Dead 2: Music disconnected from environment (Ex: checkpoint music, credit music, mob music)
SNDLVL_20dB Rustling leaves
SNDLVL_25dB Whispering
SNDLVL_30dB Library, dishwasher
SNDLVL_35dB
SNDLVL_40dB Moderate rainfall
SNDLVL_45dB Refrigerator
SNDLVL_50dB 3.9 Average home, heavy rainfall
SNDLVL_55dB 3.0 Left 4 Dead 2: Digital alarm clock in C8M1_Apartment.
SNDLVL_60dB
SNDLVL_IDLE
2.0 Normal conversation, clothes dryer
SNDLVL_65dB 1.5 Washing machine, dishwasher
SNDLVL_STATIC 1.25
SNDLVL_70dB 1.0 Car, vacuum cleaner, mixer, electric sewing machine Left 4 Dead 2: Moustachio whack smash and pop-up, tv static, whacked piano
SNDLVL_75dB
SNDLVL_NORM
0.8 Busy traffic Left 4 Dead 2: Various doors, swarm of flies, Lilpeanut audible, bullet impact on wood.
SNDLVL_80dB 0.7 Mini-bike, alarm clock, noisy restaurant, office tabulator, outboard motor, passing snowmobile, police siren Left 4 Dead 2: Jukebox, music spitter spit pile as source.
SNDLVL_TALKING Valve's chosen dialogue attenuation
SNDLVL_85dB 0.6 Average factory, electric shaver Left 4 Dead 2: Moustachio strength attract, big fire after airliner crash in C11M5_runway
SNDLVL_90dB 0.5 Screaming child, passing motorcycle, convertible ride on freeway, hair dryer Left 4 Dead 2: Moustachio strength attract, gas can bursting
SNDLVL_95dB Left 4 Dead 2: Mounted Machine Gun
SNDLVL_100dB 0.4 Subway train, diesel truck, woodworking shop, pneumatic drill, boiler shop, jackhammer Left 4 Dead 2: Music coop player in danger AKA tags (ledge hanging, pinned down by SI), Elevators.
SNDLVL_105dB Helicopter, power mower
SNDLVL_110dB Snowmobile (drivers seat), inboard motorboat, sandblasting, chainsaw Left 4 Dead 2: Boomer alert close, Van in C11M4_Terminal.
SNDLVL_120dB Car horn, propeller aircraft, concert Left 4 Dead 2: Boomer alert, Indoor fire in C1M1_Hotel, Fireworks in C2M5_Concert, Rain in "Hard Rain" campaign.
SNDLVL_125dB Left 4 Dead 2: Boomer alert far
SNDLVL_130dB Air raid siren, fireworks Left 4 Dead 2: Carousel music during crescendo event, C5M2_park perimeter alarm.
SNDLVL_GUNFIRE 0.27 Threshold of pain, gunshot, jet engine
SNDLVL_140dB 0.2 Airplane taking off, jackhammer Left 4 Dead 2: Flock of crows, Lowering bridge in C5m5_Bridge, APC engine.
SNDLVL_145dB Left 4 Dead 2: Wandering witch music ("lost little witch")
SNDLVL_150dB 0.2 Smithing hammer Left 4 Dead 2: Concert music, parade music, zombie choir, Boat Horn
SNDLVL_180dB Rocket launching

Operator stacks

See also:  Sound operators

Portal 2 engine branch introduced Operator Stacks, which are used to add complex behaviour to sounds. Outside Portal 2 Portal 2, they are supported in Counter-Strike: Global Offensive Counter-Strike: Global Offensive and Dota 2 Dota 2 (which now uses Source 2; the operator stacks have been greatly expanded upon and many of their names have been changed), Day of Infamy Day of Infamy, and Insurgency Insurgency.

Syntax

To use the operator_stacks keyvalue, a sound entry must contain the key-value pair soundentry_version 2.

There are three types of stacks, each triggered at different times:

  • prestart_stack and start_stack, executed once when a sound entry is started,
  • update_stack, executed regularly during playback,
  • stop_stack, executed once when the entry is stopped.

Inside these stacks, one can put one or multiple operators, where the key is an arbitrary operator name and the value once another keyvalues that contains the key-value pair operator <sound_operator_name> along with more key-value pairs defining what the operator does, which can be found at sound operators.

You can either start from scratch or use the import_stack command to extend a template defined in 🖿scripts\sound_operator_stacks.txt.

There are 28 operators used in Portal 2, but they are re-configured and combined in hundreds of different ways. Most of the resulting "stacks" are very specific, and this page will only deal with the more general ones.

Todo: Work out a sane way of documenting all this!

Examples

Syntax of the operator_stacks keyvalue:

entry.name
{
	channel		CHAN_STATIC
	soundlevel	SNDLVL_NONE
	volume		1.0
	wave		"common/null.wav"

	soundentry_version 2

	operator_stacks
	{
		prestart_stack	// optional
		{
			// ...
		}
		start_stack		// optional
		{
			// ...
		}
		update_stack	// optional
		{
			// ...
		}
		end_stack		// optional
		{
			// ...
		}
	}
}


Example for a start_stack referencing the operators math_random and sys_output:

entry.name
{
	// ...

	operator_stacks
	{
		start_stack
		{
			random_number	// name is arbitrary
			{
				operator	"math_random" // stores a random number (-3 <= x <= 3) inside "random_number.output"
				input_min	-3.0
				input_max	 3.0
			}
			apply_delay		// name is arbitrary
			{
				operator	"sys_output" // applies a delay to the sound (negative delay = skip into the sound)
				output		delay
				input_float	@random_number.output // accesses the output of the previous operator "random_number"
			}
		}
	}
}


Full sound entry example using import_stack:

VFX.LightFlickerEnd 
{
	channel		CHAN_AUTO
	soundlevel	SNDLVL_105db
	volume		1.0
	rndwave
	{
		wave	"vfx/light_flicker/light_flicker_end_01.wav"
		wave	"vfx/light_flicker/light_flicker_end_02.wav"
		wave	"vfx/light_flicker/light_flicker_end_03.wav"
		wave	"vfx/light_flicker/light_flicker_end_04.wav"
	}

	soundentry_version 2

	operator_stacks
	{
		start_stack // applied when the sound begins
		{
			import_stack 	"P2_exclusion_time_blocker_start" // defined in scripts/sound_operator_stacks.txt

			// We are now extending/configuring "P2_exclusion_time_blocker_start"
			// which contains an operator with the exact name "block_entries" that we edit now:

			block_entries // prevents another sound from playing
			{
				input_duration	0.25					// seconds to block for
				match_entry		"World.LightFlickerEnd"	// the sound entry to block
				match_entity	false					// only on the same entity that this sound is playing from?
			}
		}
	}
}


Limits the maximum number of sounds that can be played at once, either by sound name or entity. A sound will not stop itself from playing.

import_stack	"P2_poly_limiting_start"

limit_sound
{
	match_entry "VFX.OGSignFlicker"
	input_max_entries 3.000000
}


Smoothly transitions a sound from one location to up to eight others as the player moves through a map. An unreleased tool can auto-generate these. Position 1 is where the sound was emitted from.

Tip.pngTip:The tool mentioned above may be in the files of Dino D-Day Dino D-Day.
import_stack "p2_update_dialog_spatial_cave"

position_array
{
	input_entry_count 3
	// position 2
	input_position_1[0]	2129
	input_position_1[1]	-850
	input_position_1[2]	-1267
	// position 3
	input_position_2[0]	1473
	input_position_2[1]	-1200
	input_position_2[2]	-1343
}


Plays another sound entry.

import_stack "stop_and_play"

play_entry
{
	entry_name VFX.FizzlerDestroy
}

Sound characters

The first two characters of a WAV's name are scanned for the following:

Symbol Name Game/branch Purpose / Notes
* CHAR_STREAM all Streams from the disc, get flushed soon after. Use for one-off dialogue files or non-looping music.
# CHAR_DRYMIX all Bypasses DSP, becomes affected by the user's music volume setting (snd_musicvolume). The latter part also requires the sound to be non directional (soundlevel of 0).
Warning.pngWarning:Using this character on a sound entry utilizing an operator stack with an update_stack where the volume is zeroed out, whether by the update_stack or by the sound entry itself (volume 0.0), will cause an update_stack loop. Not only does this have negative performance implications, the sound will consume an audio channel until the loop is interrupted or the sound is stopped. [Confirm]
@ CHAR_OMNI all Non-directional sound; plays "everywhere", similar to SNDLVL_NONE, except it fades with distance from its source based on its soundlevel.
> CHAR_DOPPLER all Doppler encoded stereo: left for heading towards the listener and right for heading away.
< CHAR_DIRECTIONAL all Stereo with direction: left channel for front facing, right channel for rear facing. Mixed based on listener's direction.
Todo: Relationship with CHAR_DIRSTEREO in Counter-Strike: Global Offensive Counter-Strike: Global Offensive?
^ CHAR_DISTVARIANT all Transition distance is hard-coded, see below.
) CHAR_SPATIALSTEREO all Spatializes both channels, allowing them to be placed at specific locations within the world; see below.
Note.pngNote:Sometimes ( must be used instead, see below.
} CHAR_FAST_PITCH all Forces low quality, non-interpolated pitch shift.
$ CHAR_CRITICAL Up to Source 2006 Forces sound to be cached at a fixed point in memory.
Note.pngNote:Only affects Original Xbox Original Xbox, which streams all audio regardless of * unless marked as critical. (removed since Source 2007)
! CHAR_SENTENCE Since Source 2009 An NPC sentence.
? CHAR_USERVOX all Voice chat data. You shouldn't ever need to use this.
& CHAR_HRTF_FORCE Counter-Strike: Global Offensive Indicates wav should use HRTF spatialization for all entities (including owners).
~ CHAR_HRTF Counter-Strike: Global Offensive Indicates wav should use HRTF spatialization for non-owners.
` CHAR_HRTF_BLEND Counter-Strike: Global Offensive Indicates wav should use HRTF spatialization for non-owners, blended with stereo for sounds sufficiently close.
+ CHAR_RADIO Counter-Strike: Global Offensive Indicates a 'radio' sound -- should be played without spatialization.
$ CHAR_SUBTITLED Counter-Strike: Global Offensive Indicates the subtitles are forced.
% CHAR_MUSIC Counter-Strike: Global Offensive Indicates main menu music.
( CHAR_DIRSTEREO Counter-Strike: Global Offensive Left 4 Dead 2 Indicates directional stereo wav (like doppler).

For example:

  • 🖿)weapons/m4a1/m4_shoot.wav
  • 🖿*@npc/vo/announcer/specialoffer.wav

Spatial Stereo

Adding ) in front of a stereo sound name in the soundscript such as 🖿)weapons/m4a1/m4_shoot.wav tells the sound engine that it is a spatialized sound; this allows the sound to emit from a specific location within the world. When not used, stereo sounds play in a fixed 2-channel orientation and cannot be panned to simulate a location. Single-channel files do not require ) before the filename and will be spatialized automatically.

Soundscapes

Soundscapes have special needs. Stereo wave files used in PlayRandom require that ( is placed before the filename. PlayLooping still uses ) but ( will spatialize the two channels separately for an alternate effect; ( sounds more environmental, but the exact nature of this behavior is unknown. Generic soundscripts can sometimes use ( to gain the same stereo spatialization that occurs in PlayLooping.

Confirm:Is this ( stereo-spatialization behavior present in all engine branches? Some preliminary testing reveals it may be absent from Garry's Mod Garry's Mod.
Example
wave ")ambient/stereo_alarm.wav" // Typical usage in a standard soundscript

But in soundscapes:

playrandom
{
	time		33,68
	volume		.6,1
	pitch		90,105
	position	0
	rndwave
	{
		wave "ambient/mono_siren.wav" // Mono files are always spatialized properly
		wave ")ambient/stereo_alarm.wav" // WRONG; sound will not be spatialized
		wave "(ambient/stereo_siren.wav" // Correct; sound will be spatialized normally
	}
}
PlayLooping
{
	volume		.6
	pitch		100
	position	0
	wave		")ambient/stereo_siren.wav" // standard spatialization; both channels originate at same location
	//wave		"(ambient/stereo_siren.wav" // stereo spatialization; one of the channels is spatialized alternatively
}

Distance variance in Source

Adding ^ in front of a sound name, such as 🖿^weapons/explode3.wav tells the sound engine that it is a distance based sound. The left channel of the sound file is the 'near' sound that will play when the sound originates close to you, and the right channel is the 'far' sound that will play when the sound originates far from you. If the ^ mark is not used in the soundscript, the sound is treated as stereo with no directionality or distance. This is a different feature than the soundlevel property to control attenuation. This distant variant feature allows you to play two different sounds (but using only one file) and crossfading between the two depending on how far away the sound originates.

The fade distances are hardcoded to begin at 240 world units and end at 1320 world units, and cannot be changed in custom maps or mods.

See also



  • 🖿src\public\soundflags.h
  • 🖿src\public\soundchars.h
  • 🖿scripts\game_sounds_header.txt
  • 🖿scripts\game_sounds.txt