Soundmixer

From Valve Developer Community
Jump to navigation Jump to search

Overview

The levels, DSP volumes, and relative sound volumes of different sounds can be set using the SoundMixer system, which is configured in soundmixers.txt.

Each sound is assigned MixGroups based on specific filters at runtime, using the file name/directory (matched by substring), entity classname, channel, and soundlevel.

There are hard coded limits to the number of configurations possible in this system:

  • Up to 64 unique mix groups
  • Up to 76 group rules entries
  • Up to 32 sound mixers
  • All strings are limited to 31 characters!

MixGroups

MixGroups are used to categorize various sounds. They are defined by a name, filters and their properties. For a sound to be assigned a MixGroup, it must match all the specified filters of that group. Each sound can be assigned to at maximum 8 mix groups.

There are

  1. Directory or .wav name substring - whitelists sounds whose filename/directory matches the substring. e.g. a door substring would match both door.wav and doors/gate.wav
  2. Classname substring - whitelists sounds where the source entity's classname matches this substring
  3. Channel - whitelists sounds playing in a specific channel
  4. Soundlevel minimum - whitelists sounds above this Soundlevel value
  5. Soundlevel maximum - whitelists sounds below this Soundlevel value

Besides filters, the MixGroup configuration also includes sound ducking properties (fields priority, is_ducked, causes_ducking, duck_to_percent, ducker_threshold). Sound ducking allows sounds with a high priority value to lower the volume of sounds with lower priority. Also, higher priority sounds need to have causes_ducking, and the lower priority sounds must have is ducked set. Since Left 4 Dead 2 Left 4 Dead 2 (and including Portal 2), the MixLayer system (explained below) was introduced to allow modification of relative volumes of sounds with greater precision. This system is commonly used to replace ducking, though both systems can be used at once if needed.


In Strata Source a new property was added to the very end. This property binds a snd_volume_X ConVar to a MixGroup, making sounds playing from that group scale their volume with this ConVar.

The example below shows a sample configuration of three mixgroups:

MixGroups {
    // group name         | directory or .wav name | classname | channel | sndlvl_min | sndlvl_max | priority | is ducked | causes ducking | duck to % | duck threshold |  Volume ConVar (only in Strata) 
    "awesome_sounds"      "awesome_sounds/"             ""         ""         ""          ""           "100"        "0"            "0"           "100"          "0"       
    "not_awesome_sounds"  "not_awesome_sounds/"         ""         ""         ""          ""           "100"        "0"            "0"           "100"          "0"       
    "weird_sounds"        "weird_sounds/"               ""         ""         ""          ""           "100"        "0"            "0"           "100"          "0"       
    "music"               "music/"                      ""         ""         ""          ""           "100"        "0"            "0"           "100"          "0"       "snd_volume_music"

}

Any combinations of these filters can be used, and a sound will only be assigned a MixGroup if it matches all the specified filters. If filtering by one of this criteria is undesired, the filter should be set to an empty string "".

Order

Importantly, even though a sound can be assigned various MixGroups (if it matches the filters of more than one group), only the first MixGroup that it matches, from the top to the bottom of the MixGroups configuration, will affect its properties. Therefore, the order of MixGroups in their configuration is extremely important, and should be done (top to bottom) from least generic to most generic. For example, it's common to have an "All" MixGroup (with no filters) as a default/placeholder group for generic sounds. Since this group is the most generic possible (including all sounds), it should be the last entry in the list. If it is at the top of the list, every sound will be assigned to that group first and will override any custom settings for different sounds.


SoundMixers

During gameplay, only one SoundMixer (a.k.a. a 'Mix') can be active at a time. The SoundMixer specifies the volume, level, DSP volume, Solo, and Mute values for each MixGroup (similar to how a hardware/software audio mixer handles the volume of different channels). Different SoundMixers can be configured in soundmixers.txt. For example, in PortalPortal 2 Portal 2 the Default_Mix handles most gameplay.

For each MixGroup inside a SoundMixer, there are 5 properties which can be defined, each with float value ranging from 0.0 to 1.0:

  1. Volume - scales the volume of sounds of this MixGroup
  2. Level - scales the level of sounds of this MixGroup
  3. DSP - scales the volume of DSP of this MixGroup
  4. Solo - decreases the volume of every other MixGroup besides this one (soloing this MixGroup). Multiple MixGroups can be soloed at once. A value of 1.0 effectively mutes every other sound, and a value of 0.0 is the default volume.
  5. Mute - decreases the volume of this MixGroup without affecting other MixGroups. Multiple MixGroups can be muted at once. A value of 1.0 mutes the MixGroup completely, and a value of 0.0 is the default volume.
SoundMixers {
   "Default_Mix" {
      "awesome_sounds"     "1.0" "1.0" "1.0" "0.0" "0.0" // An example default setting
      "not_awesome_sounds" "0.6" "1.0" "1.0" "0.0" "0.0" // In this example, this MixGroup has a lower volume than awesome_sounds
      "weird_sounds"       "0.3" "1.0" "1.0" "0.0" "0.0" // a low default volume for weird sounds
      "music"              "0.7" "1.0" "1.0" "0.0" "0.0" // a normal volume for music
   }
   "Less_Awesome_Mix" {
      "awesome_sounds"     "0.0" "1.0" "1.0" "0.0" "1.0" // In this SoundMixer we mute the volume awesome_sounds
      "not_awesome_sounds" "1.0" "1.0" "1.0" "0.0" "0.0" // and raise the volume of not_awesome_sounds
      "weird_sounds"       "0.3" "1.0" "1.0" "0.0" "0.0" // same properties as in the Default_Mix
   }

}

You can specify which SoundMixer is active with the command snd_soundmixer

A sound is only controlled by a SoundMixer if its MixGroup is explicitly configured in the current SoundMixer. In the above example, the Less_Awesome_Mix lacks the music MixGroup, and will therefore not affect the properties of this MixGroup.



MixLayers and LayerTriggers

The MixLayers system was introduced in Left 4 Dead 2 Left 4 Dead 2. MixLayers allow sounds from a specific MixGroup to trigger temporary changes to the same 5 properties defined in the current SoundMixer. This layers the configuration of the MixLayer on top of the current SoundMixer. Each property is calculated by mixing the current SoundMixer properties and the current active MixLayer(s). Multiple MixLayers can be active at once.

MixLayers {
   "Weird_Sounds_Playing" {
          "weird_sounds"       "1.0" "1.0" "1.0" "0.8" "0.0" // This ''soloes'' the the weird_sounds MixGroup, lowering other sounds by 80% when this MixLayer is active.
          "awesome_sounds"     "1.0" "1.0" "1.0" "0.0" "0.0" // The volume of this MixGroup will be lowered by 80% when this MixLayer is active.
          "not_awesome_sounds" "1.0" "1.0" "1.0" "0.0" "0.0" // The volume of this MixGroup will be lowered by 80% when this MixLayer is active.
          // any sound not in this MixLayer will be unaffected by triggering this layer
   }
}

For a MixLayer to be active, it must be triggered by a sound from a specific MixGroup (e.g. a sound in the weird_sounds MixGroup can trigger the Weird_Souds_Playing MixLayer). A MixLayer is only active while the trigger is active. After this, the layer will be deactivated and will stop having any effect on the sound.

The triggers for MixLayers are defined in Layer_Triggers. Each MixLayer is triggered by sounds coming from a specified MixGroup. These triggers must be configured with the following 5 properties:

  1. The MixLayer we want to trigger
  2. The MixGroup which activates triggers the MixLayer
  3. A threshold above which the layer is triggered. The intended usage here is that the current volume of the sound (a float from 0.0 to 1.0) is compared to the value of the threshold. If its value is higher, the trigger is active. In the Portal 2 sound_operator_stacks, this nuanced behavior is skipped by setting the value to 0.0, and triggering sounds just send a value of 1.0 which guarantees the trigger.
  4. The factor of the MixLayer, which affects the relative proportion with which its properties are mixed with the active SoundMixer. In the Weird_Sounds_Playing layer above, a factor of 0.5 would halve the solo of this MixLayer.
  5. The attack of the trigger: a float value specifying the duration (in seconds) that the changes of the MixLayer ramp up to. For example, an attack of 1.0 of the Weird_Sounds_Playing layer above would make the solo effect of weird_sounds ramp up over 1 second.
  6. The release of the trigger: a float value specifying the duration (in seconds) that the MixLayer takes to deactivate after the trigger is off. A release of 2.0 of the Weird_Sounds_Playing layer above will make it so when the MixLayer is no longer active (e.g. when the triggering sound is over), the system will take 2.5 seconds to gradually adjust the properties back to the current SoundMixer configuration.

The code below shows a sample configuration of the 5 properties explained above:

"LayerTriggers"
{
//			MixLayer			|		Triggering MixGroup			|	Threshold	| 	Factor	|	Attack	|	Release

	"Weird_Sounds_Playing"				"weird_sounds"					"0.0"			"1.0"		"1.0"		"2.5"

}

Usage in soundscapes

Soundmixers can be used to ensure that important dialogue is clearly heard despite ambient noise, sounds of combat, or other characters talking; to tone down excessively loud effects and preventing them from drowning out sounds; to imitate feeling of concussion or hearing loss; even to make surreal-sounding soundscapes where playback of sounds defies conventional expectations.

An example of usage: Team Fortress 2 Team Fortress 2 uses a freeze-cam specific soundmixer to quieten most sounds in the game except for player dialog and important sound cue.

Soundmixers can be applied within soundscapes. A soundscape can define an existing soundmixer and, when that soundscape is active, the soundmixer will adjust the volume of the sounds based on the soundmixer's rules.

Note.pngNote: All soundscapes use soundmixer "Default_Mix" unless another is specified. That means that transitioning from a soundscape with your soundmixer, to another, even if it doesn't explicitly specify a soundmixer, will cause it to reset to "Default_Mix".
Tip.pngTip: The active soundmixer can be seen (and specified) by using snd_soundmixer command.
Tip.pngTip: Use command snd_showmixer 1 to turn on the mixer interface which lets you see the mix groups in use, their mix values and volume meter during playback.
Tip.pngTip: snd_showclassname 2 shows the mixer rule that new sounds get matched to.


For example, creating a new SoundMixer for a specific soundscape:

"SoundMixers"
{
      ...

      "soundmixer_test"
      {
	      "awesome_sounds" 		"0.05"
	      "not_awesome_sounds"    "1.0"
      }
}

And referencing it in the soundscape

soundscape_test
{	
	"soundmixer" "soundmixer_test"
	
	// the rest is whatever your soundscape is...
	"dsp" "1"
}

Will mean that, while that soundscape is active, all sounds matching the group rule (in that example, all sounds down the path of sound\awesome_sounds/) play only at 5% of their normal volume, and not_awesome_sounds at max volume. This applies to any sounds matching the group criteria, not just the ones emitted by the active soundscape - so it will affect ambient_generics, NPC, gunfire, etc.

Other examples:

Using a soundmixer to tone down a particularly loud sound effect

Add this within GROUPRULES table, toward the top for more specific rules, or toward the bottom for more general rules

This rule looks up sounds that are in the dropship folder AND are loud (soundlevel above 120 dB)

"Dropship_Fly" "/combine_gunship/dropship_" ""	""	"121"	""	"50"	"0"	"0"	"100"	"0"

Add this entry below GROUPRULES table:

"soundmixer_quiet_dropship"
{
	// the dropship fly loop is overbearing in our map. Tone it down in the soundscapes in the area where it's heard.
	"Dropship_Fly"			"0.40"

	// the rest of values is copied from Valve's "Default_mix"
	"Explosions"			"0.90"
	"Player_Weapons_Loud"	"1.0"
	"Player_Suit"			"0.56"
	"Weapons"				"0.79"

	"AHELI_WEAPON"			"0.85"
	"GUNSHIP_WEAPON"		"0.85"
	"STRIDER_WEAPON"		"0.85"
	"bullethit"				"0.67"
	
	"Music"					"1.0"
	
	"All"					"0.72"
}

Reference your soundmixer in the soundscape:

soundscape_dropship_area // the area where dropship flies by
{	
	"soundmixer" "soundmixer_quiet_dropship"
	
	// the rest is whatever your soundscape is...
	"dsp" "1"
	"playsoundscape" "d1_canals_watercanal"
}
Todo: Add explanation on ducking.
The quick summary is sounds with high priority that have "causes ducking" "1" will cause sounds with lower priority than them, that also have "is ducked" "1", to become muffled during high priority sounds' playback.

Game-specific soundmixer list