Class SoundEventPlayer
Namespace: ValveResourceFormat.Renderer.Audio
Assembly: Renderer.dll
Plays sound events through an injected . Owns a mixing thread that continuously mixes active sounds and submits the samples to the device.
public sealed class SoundEventPlayer : IDisposableInheritance
Implements
Constructors
SoundEventPlayer(IFileLoader, IAudioDevice, ILogger?)
Creates a sound event player. Takes ownership of device and starts the mixing thread immediately.
public SoundEventPlayer(IFileLoader fileLoader, IAudioDevice device, ILogger? logger = null)Parameters
fileLoader IFileLoader
device IAudioDevice
logger ILogger?
Properties
Bank
Gets the bank of loaded sound event definitions.
public SoundEventBank Bank { get; }Property Value
DefaultMixGroupVolume
Gets or sets the fallback volume multiplier for mix groups without an explicit
entry.Events without any mix group are not affected and play at authored volume.
public float DefaultMixGroupVolume { get; set; }Property Value
MixDutyCycle
Gets the share of real time the mixing thread spends mixing rather than waiting on the device, 0 to 1 - effectively how much of one core the audio costs.
public float MixDutyCycle { get; }Property Value
MixGroupVolume
Gets the volume multipliers per mix group ("mixgroup" in the sound event data, e.g. "Weapons", "Footsteps"). A crude stand-in for the game's mix graph: groups without an entry play at full volume. Applies to sounds started after the change.
public Dictionary<string, float> MixGroupVolume { get; }Property Value
MixMilliseconds
Gets the recent average time spent mixing one chunk, in milliseconds.
public float MixMilliseconds { get; }Property Value
Mute
Gets or sets whether the player is muted, independently of and with no fade. While silent, the mixing thread skips decoding/mixing entirely instead of mixing to silence.
public bool Mute { get; set; }Property Value
OcclusionTrace
Optional line-of-sight test for sound occlusion: given the listener position and a sound position, returns true when solid geometry blocks the segment. When set, events with an "occlusion_intensity" are attenuated while blocked (e.g. a distant moped behind buildings); when null nothing is occluded.
public Func<Vector3, Vector3, bool>? OcclusionTrace { get; set; }Property Value
SampleRate
Gets the mixer output sample rate, taken from the device.
public int SampleRate { get; }Property Value
SoundCache
Gets the decoded sound store.
public SoundCache SoundCache { get; }Property Value
Soundscapes
Gets the bank of loaded scripted soundscape definitions (see ).
public SoundscapeBank Soundscapes { get; }Property Value
Suspended
Gets or sets whether output is suspended, fading to silence and back so focus/tab changes don't snap the audio. Unlike , sounds keep advancing in real time while suspended (just inaudible) so a sound triggered mid-suspend is at the correct position, not frame 0, once resumed.
public bool Suspended { get; set; }Property Value
Volume
Gets or sets the master output volume (0..1), applied to the final mix on top of per-sound and mix group volumes. Mapped onto the same perceptual curve as the per-sound volume controls. Safe to set live from any thread; the mixing thread picks it up on its next chunk.
public float Volume { get; set; }Property Value
Methods
AddScriptedSoundscape(Vector3, float, string)
Registers a soundscape region playing a "scripted" soundscape (a classic env_soundscape without "enablesoundevent" set): every sound event soundscapeName resolves to, via , starts together when the region becomes active. Requires
public void AddScriptedSoundscape(Vector3 position, float radius, string soundscapeName)Parameters
position Vector3
radius float
soundscapeName string
AddSoundscape(Vector3, float, string)
Registers a soundscape region playing a single sound event directly (a modern env_soundscape with "enablesoundevent" set). The closest in-range soundscape becomes the active ambient during ; entering another region crossfades by stopping the previous event(s).
public void AddSoundscape(Vector3 position, float radius, string soundEventName)Parameters
position Vector3
radius float
soundEventName string
Cache(string)
Pre-warms a sound event so its first real play does no lazy work on the frame: builds the full instance tree (event instances, providers, child wiring) into the definition's pool, and queues background decodes for every vsnd the tree could pick. Also safe to call again while approaching an already-warm event - the instance work is a no-op and the decode queueing just refreshes the sounds' cache eviction age. Returns immediately; sounds that want to play right now take priority over the queued decodes. Unknown events and unsupported types are ignored.
public void Cache(string soundEventName)Parameters
soundEventName string
CollectDebugSounds(List<(Vector3 Position, string Text)>, List<string>)
Collects the position and vsnd name of every audible positioned sound into positioned, and the vsnd name of every audible non-positioned (2D) sound into flat.
public void CollectDebugSounds(List<(Vector3 Position, string Text)> positioned, List<string> flat)Parameters
positioned List<(Vector3 Position, string Text)>
Dispose()
Stops the mixing thread and disposes the mixer and the audio device.
public void Dispose()GetMixGroupVolume(string)
Gets the volume multiplier for a mix group: its entry,
for unknown groups, and 1 when the event has no group.public float GetMixGroupVolume(string mixGroup)Parameters
mixGroup string
Returns
LoadSoundEvents(string)
Loads sound event definitions from all soundevent files listed in the game's soundevents manifest, plus when present. An optional filter matches against the file name (e.g. "game_sounds").
public void LoadSoundEvents(string filter = "")Parameters
filter string
LoadSoundEventsFile(string, bool)
Loads sound event definitions from a single soundevent (vsndevts) file. When optional is set, a missing file is skipped quietly instead of logging a warning (see ).
public void LoadSoundEventsFile(string fileName, bool optional = false)Parameters
fileName string
optional bool
LoadSoundscapes()
Loads scripted soundscape definitions (see ) from the game's "scripts/soundscapes_manifest.txt", when present. Most modern titles only use the newer single-sound-event soundscapes (see ), which need no separate loading step, so a missing manifest is not an error.
public void LoadSoundscapes()Play(string, Vector3?, string?, float?)
Plays a sound event by name. Allocation-free once a definition has played before: instances are pooled per definition and reused (with their whole provider tree) once fully stopped.
public SoundEvent? Play(string soundEventName, Vector3? position = null, string? channel = null, float? volume = null)Parameters
soundEventName string
Name of the sound event, e.g. "Default.StepLeft".
position Vector3?
World position of the sound, or null for non-spatialized playback.
channel string?
Optional channel name (e.g. "player"). Playing on a channel stops whatever was playing on that channel before.
volume float?
Optional programmatic volume, replacing the definition's volume property.
Returns
A handle to the playing sound, or null when the event is unknown, its type is unsupported, or it produced nothing (empty track list, dropped by its limiter). The handle is only meaningful while the sound is : once it stops, the instance returns to its definition's pool and a later play of the same event may hand the same instance out again.
StopChannel(string)
Stops the sound currently playing on the given channel, if any.
public void StopChannel(string channel)Parameters
channel string
Update(Camera)
Updates listener position and per-frame sound event logic, and claims as the active global listener. Call once per frame, only for the viewer currently active/visible - calling this from every open viewer's own renderer, active or not, would have each one stomp on whichever is the current global listener.
public void Update(Camera camera)Parameters
camera Camera

