ISource2ModSounds
Interface for playing, stopping and rewriting sound events.
A sound event reaches a client as one network message (CMsgSosStartSoundEvent): the hash of its name, the entity it plays from, a guid and a packed block of parameters. This interface builds and sends that message itself instead of going through an entity on the server, which is what makes the rest possible:
- a sound goes to exactly the players you pick -- nobody else receives it, so there is nothing for them to hear;
- Emit() hands back the guid, and the guid stops the sound at once or changes its parameters while it plays;
- volume channels: a player's own volume for "music", "effects" or whatever a plugin names is applied per recipient, so a player turns the server's music down in a menu instead of fighting snd_musicvolume;
- every sound the game itself starts passes through HookSound(), where it can be blocked, renamed, re-parametrised or re-addressed.
Interface id ISource2ModSounds002 (SOURCE2MOD_SOUNDS_INTERFACE) · Global g_pSource2ModSounds · Header source2mod/ISource2ModSounds.h
Types
Source2ModSoundHookId
using Source2ModSoundHookId = Source2ModHookId;A sound hook (HookSound).
SoundGuid
using SoundGuid = uint32_t;Identifies one playing sound on the clients it was sent to.
Taken from the engine's own counter, so it never collides with a sound the game started. 0 means "nothing was sent".
SoundRecipients
using SoundRecipients = uint64_t;Recipient set, one bit per player slot (bit N = slot N).
SoundHook
using SoundHook = Source2ModCallback<Action(ISource2ModSound* sound)>;Hook called for every sound the game is about to send to clients.
Sounds sent through this interface do not come back through the hook.
Methods
CreateSound
virtual ISource2ModSound* CreateSound(PluginId owner, const char* name = nullptr) = 0;Creates a sound: listener-sourced, volume and pitch 1, no recipients.
ISource2ModSound::New() is the usual way in. Release with delete or DestroySound(); whatever a plugin leaves behind goes when it unloads.
| Parameter | Type | Default | Description |
|---|---|---|---|
owner | PluginId | Plugin ID that owns the sound | |
name | const char* | nullptr | Sound event name, may be set later |
DestroySound
virtual void DestroySound(ISource2ModSound* sound) = 0;| Parameter | Type |
|---|---|
sound | ISource2ModSound* |
EmitSoundToPlayer
virtual SoundGuid EmitSoundToPlayer(CPlayerSlot slot, const char* name, float volume = 1.0f, float pitch = 1.0f, const char* channel = nullptr) = 0;Plays a sound for one player only, at the listener.
| Parameter | Type | Default |
|---|---|---|
slot | CPlayerSlot | |
name | const char* | |
volume | float | 1.0f |
pitch | float | 1.0f |
channel | const char* | nullptr |
EmitSoundToPlayers
virtual SoundGuid EmitSoundToPlayers(SoundRecipients recipients, const char* name, float volume = 1.0f, float pitch = 1.0f, const char* channel = nullptr) = 0;Plays a sound for a set of players, at each listener.
| Parameter | Type | Default |
|---|---|---|
recipients | SoundRecipients | |
name | const char* | |
volume | float | 1.0f |
pitch | float | 1.0f |
channel | const char* | nullptr |
EmitSoundToAll
virtual SoundGuid EmitSoundToAll(const char* name, float volume = 1.0f, float pitch = 1.0f, const char* channel = nullptr) = 0;Plays a sound for everybody, at each listener.
| Parameter | Type | Default |
|---|---|---|
name | const char* | |
volume | float | 1.0f |
pitch | float | 1.0f |
channel | const char* | nullptr |
EmitSoundFromEntity
virtual SoundGuid EmitSoundFromEntity(CEntityInstance* entity, const char* name, float volume = 1.0f, float pitch = 1.0f, SoundRecipients recipients = ~SoundRecipients(0), const char* channel = nullptr) = 0;Plays a sound from an entity, for @p recipients (everybody by default).
| Parameter | Type | Default |
|---|---|---|
entity | CEntityInstance* | |
name | const char* | |
volume | float | 1.0f |
pitch | float | 1.0f |
recipients | SoundRecipients | ~SoundRecipients(0) |
channel | const char* | nullptr |
StopSound
virtual void StopSound(SoundGuid guid) = 0;Stops a sound at once, for everybody it was sent to.
| Parameter | Type |
|---|---|
guid | SoundGuid |
StopSoundForPlayers
virtual void StopSoundForPlayers(SoundGuid guid, SoundRecipients recipients) = 0;Stops a sound for some of its recipients; it keeps playing for the rest.
| Parameter | Type |
|---|---|
guid | SoundGuid |
recipients | SoundRecipients |
StopSoundByName
virtual void StopSoundByName(const char* name, int sourceEntityIndex = SOUND_SOURCE_LISTENER, SoundRecipients recipients = ~SoundRecipients(0)) = 0;Stops a sound by name, including one the game started.
| Parameter | Type | Default | Description |
|---|---|---|---|
name | const char* | Sound event name | |
sourceEntityIndex | int | SOUND_SOURCE_LISTENER | Entity the sound plays from, SOUND_SOURCE_LISTENER for sounds without one |
recipients | SoundRecipients | ~SoundRecipients(0) | Who to stop it for, everybody by default |
SetSoundVolume
virtual void SetSoundVolume(SoundGuid guid, float volume) = 0;Changes the volume of a playing sound. Channel volumes still apply.
| Parameter | Type |
|---|---|
guid | SoundGuid |
volume | float |
UpdateSoundParams
virtual void UpdateSoundParams(SoundGuid guid, const ISource2ModSound* params, SoundRecipients recipients = SOUND_RECIPIENTS_NONE) = 0;Sends the parameters of @p params to a playing sound.
Only the parameters set on @p params are sent; its name, source and recipients are ignored.
| Parameter | Type | Default | Description |
|---|---|---|---|
guid | SoundGuid | ||
params | const ISource2ModSound* | ||
recipients | SoundRecipients | SOUND_RECIPIENTS_NONE | Who to send to, 0 for everybody the sound went to |
SetPlayerVolume
virtual void SetPlayerVolume(CPlayerSlot slot, const char* channel, float volume) = 0;Sets one player's volume for a channel (0 mutes, 1 is unchanged).
A channel is just a name sounds are emitted under ("music", "effects", ...). Applies to every later sound on the channel, and straight away to the ones this player is still hearing: they get louder, quieter, or stop. Forgotten when the player disconnects -- Source2Mod keeps nothing on disk, load it from wherever the plugin stores preferences.
| Parameter | Type |
|---|---|
slot | CPlayerSlot |
channel | const char* |
volume | float |
GetPlayerVolume
virtual float GetPlayerVolume(CPlayerSlot slot, const char* channel) = 0;A player's volume for a channel, 1.0 when never set.
| Parameter | Type |
|---|---|
slot | CPlayerSlot |
channel | const char* |
ResetPlayerVolumes
virtual void ResetPlayerVolumes(CPlayerSlot slot) = 0;Puts all of a player's channels back to 1.0.
| Parameter | Type |
|---|---|
slot | CPlayerSlot |
HashSoundName
virtual uint32_t HashSoundName(const char* name) = 0;Hash a sound event name travels as, for matching a hooked sound:
static const uint32_t knifeHit = g_pSource2ModSounds->HashSoundName("Weapon_Knife.Hit"); if (sound->GetNameHash() == knifeHit) ...
The name is remembered, so ISource2ModSound::GetName() and LookupSoundName() resolve it from then on.
| Parameter | Type |
|---|---|
name | const char* |
LookupSoundName
virtual const char* LookupSoundName(uint32_t hash) = 0;Name for a hash, nullptr when Source2Mod has not seen it.
| Parameter | Type |
|---|---|
hash | uint32_t |
HookSound
virtual Source2ModSoundHookId HookSound(SoundHook handler) = 0;Hooks the sounds the game sends to clients.
A plugin may hook as often as it likes; each handler runs.
Whose it is, the core reads off the handler (see Source2ModCallback); what a plugin still holds at unload the core drops for it.
| Parameter | Type | Description |
|---|---|---|
handler | SoundHook | A function, an object and a method, or a lambda |
Returns Source2ModSoundHookId — The id UnhookSound(id) takes
UnhookSound
virtual bool UnhookSound(const SoundHook& handler) = 0;
virtual bool UnhookSound(Source2ModSoundHookId id) = 0;Drops the hook with this handler -- a function or an object and a method; a lambda goes by its id.
Drops the hook HookSound() returned the id for.
| Parameter | Type |
|---|---|
handler | const SoundHook& |
id | Source2ModSoundHookId |
Returns bool — true when one was found
ISource2ModSound
One sound event: what to play, from where, how, and for whom.
Made with ISource2ModSound::New(), released with delete, and reusable in between -- Emit() may be called any number of times, each call is a new sound with a new guid. The same type is what a HookSound() handler receives for a sound the game is about to send.
Parameter names are the sound event's public fields ("public.volume", "public.pitch", "public.position", or whatever a custom .vsndevts declares). They travel as hashes, so a name cannot be listed back, only asked for.
SetName
virtual void SetName(const char* name) = 0;Sets the sound event to play, e.g. "Weapon_AK47.Single".
| Parameter | Type |
|---|---|
name | const char* |
GetName
virtual const char* GetName() const = 0;Sound event name, or "" when only its hash is known.
A hooked game sound arrives as a hash, and a hash cannot be turned back into a name. Source2Mod resolves it against the names it has been given so far -- everything emitted through this interface and everything passed to ISource2ModSounds::HashSoundName() -- so the sounds a plugin looks for come out named, the rest as "".
SetNameHash
virtual void SetNameHash(uint32_t hash) = 0;| Parameter | Type |
|---|---|
hash | uint32_t |
GetNameHash
virtual uint32_t GetNameHash() const = 0;GetGuid
virtual SoundGuid GetGuid() const = 0;Guid of the sound. Assigned by the engine for a hooked sound, by the last Emit() otherwise (0 before the first one).
SetSourceEntityIndex
virtual void SetSourceEntityIndex(int index) = 0;Entity index the sound plays from and follows, or SOUND_SOURCE_LISTENER (default) / SOUND_SOURCE_WORLD.
| Parameter | Type |
|---|---|
index | int |
GetSourceEntityIndex
virtual int GetSourceEntityIndex() const = 0;SetSourceEntity
virtual void SetSourceEntity(CEntityInstance* entity) = 0;Plays the sound from an entity. nullptr is SOUND_SOURCE_LISTENER.
| Parameter | Type |
|---|---|
entity | CEntityInstance* |
SetPosition
virtual void SetPosition(const Vector& position) = 0;Plays the sound at a point in the world: SOUND_SOURCE_WORLD plus "public.position".
| Parameter | Type |
|---|---|
position | const Vector& |
SetVolume
virtual void SetVolume(float volume) = 0;"public.volume". 1.0 is the sound event's own volume.
With a channel set, each recipient gets this multiplied by their own volume for that channel.
| Parameter | Type |
|---|---|
volume | float |
GetVolume
virtual float GetVolume() const = 0;SetPitch
virtual void SetPitch(float pitch) = 0;"public.pitch". 1.0 is unchanged.
| Parameter | Type |
|---|---|
pitch | float |
GetPitch
virtual float GetPitch() const = 0;SetChannel
virtual void SetChannel(const char* channel) = 0;Volume channel this sound belongs to, or nullptr/"" for none.
See ISource2ModSounds::SetPlayerVolume(). A recipient whose volume for the channel is 0 is not sent the sound at all.
| Parameter | Type |
|---|---|
channel | const char* |
GetChannel
virtual const char* GetChannel() const = 0;HasParam
virtual bool HasParam(const char* name) const = 0;| Parameter | Type |
|---|---|
name | const char* |
GetParamType
virtual SoundParamType GetParamType(const char* name) const = 0;| Parameter | Type |
|---|---|
name | const char* |
RemoveParam
virtual void RemoveParam(const char* name) = 0;| Parameter | Type |
|---|---|
name | const char* |
ClearParams
virtual void ClearParams() = 0;SetBool
virtual void SetBool(const char* name, bool value) = 0;| Parameter | Type |
|---|---|
name | const char* |
value | bool |
SetInt32
virtual void SetInt32(const char* name, int32_t value) = 0;| Parameter | Type |
|---|---|
name | const char* |
value | int32_t |
SetUInt32
virtual void SetUInt32(const char* name, uint32_t value) = 0;| Parameter | Type |
|---|---|
name | const char* |
value | uint32_t |
SetUInt64
virtual void SetUInt64(const char* name, uint64_t value) = 0;| Parameter | Type |
|---|---|
name | const char* |
value | uint64_t |
SetFloat
virtual void SetFloat(const char* name, float value) = 0;| Parameter | Type |
|---|---|
name | const char* |
value | float |
SetFloat3
virtual void SetFloat3(const char* name, const Vector& value) = 0;| Parameter | Type |
|---|---|
name | const char* |
value | const Vector& |
GetBool
virtual bool GetBool(const char* name, bool def = false) const = 0;Typed getters. @p def comes back when the parameter is missing or of another type.
| Parameter | Type | Default |
|---|---|---|
name | const char* | |
def | bool | false |
GetInt32
virtual int32_t GetInt32(const char* name, int32_t def = 0) const = 0;| Parameter | Type | Default |
|---|---|---|
name | const char* | |
def | int32_t | 0 |
GetUInt32
virtual uint32_t GetUInt32(const char* name, uint32_t def = 0) const = 0;| Parameter | Type | Default |
|---|---|---|
name | const char* | |
def | uint32_t | 0 |
GetUInt64
virtual uint64_t GetUInt64(const char* name, uint64_t def = 0) const = 0;| Parameter | Type | Default |
|---|---|---|
name | const char* | |
def | uint64_t | 0 |
GetFloat
virtual float GetFloat(const char* name, float def = 0.0f) const = 0;| Parameter | Type | Default |
|---|---|---|
name | const char* | |
def | float | 0.0f |
GetFloat3
virtual Vector GetFloat3(const char* name, const Vector& def = Vector(0, 0, 0)) const = 0;| Parameter | Type | Default |
|---|---|---|
name | const char* | |
def | const Vector& | Vector(0, 0, 0) |
AddRecipient
virtual void AddRecipient(CPlayerSlot slot) = 0;| Parameter | Type |
|---|---|
slot | CPlayerSlot |
RemoveRecipient
virtual void RemoveRecipient(CPlayerSlot slot) = 0;| Parameter | Type |
|---|---|
slot | CPlayerSlot |
HasRecipient
virtual bool HasRecipient(CPlayerSlot slot) const = 0;| Parameter | Type |
|---|---|
slot | CPlayerSlot |
AddAllRecipients
virtual void AddAllRecipients() = 0;Every player connected at the moment of the call -- the ones with a net channel, so bots are left out (a sound cannot reach them).
ClearRecipients
virtual void ClearRecipients() = 0;SetRecipients
virtual void SetRecipients(SoundRecipients mask) = 0;| Parameter | Type |
|---|---|
mask | SoundRecipients |
GetRecipients
virtual SoundRecipients GetRecipients() const = 0;Recipient set, one bit per player slot (bit N = slot N).
Emit
virtual SoundGuid Emit() = 0;Sends the sound to its recipients.
Returns SoundGuid — Guid of the new sound, 0 when there was nobody to send it to.
New
static ISource2ModSound* New(const char* name = nullptr);Creates a sound: listener-sourced, volume and pitch 1, no recipients.
Equivalent to g_pSource2ModSounds->CreateSound(g_PluginID, name). Release with delete or g_pSource2ModSounds->DestroySound().
ISource2ModSound* music = ISource2ModSound::New("jb.duel"); music->SetChannel("music"); music->AddAllRecipients(); SoundGuid guid = music->Emit(); delete music;
| Parameter | Type | Default | Description |
|---|---|---|---|
name | const char* | nullptr | Sound event name, may be set later with SetName(). |
Enums
SoundParamType
enum class SoundParamType : uint8_tWire type of a packed sound parameter.
The engine knows more than these; they are the ones whose layout is known, and every public parameter of the stock sound events is one of them. Parameters of any other type on a hooked sound are carried through untouched.
| Name | Value |
|---|---|
Invalid | 0 |
Bool | 1 |
Int32 | 2 |
UInt32 | 3 |
UInt64 | 4 |
Float | 8 |
Float3 | 10 |
Functions
SoundRecipientOf
inline SoundRecipients SoundRecipientOf(CPlayerSlot slot);Recipient mask of one slot.
| Parameter | Type |
|---|---|
slot | CPlayerSlot |
Macros
SOUND_EMIT_TO_PLAYER
#define SOUND_EMIT_TO_PLAYER(slot, ...) g_pSource2ModSounds->EmitSoundToPlayer(slot, __VA_ARGS__)Shorthand accessors via g_pSource2ModSounds.
Other macros
| Macro | Expands to |
|---|---|
SOUND_EMIT_TO_PLAYERS(mask, ...) | g_pSource2ModSounds->EmitSoundToPlayers(mask, __VA_ARGS__) |
SOUND_EMIT_TO_ALL(...) | g_pSource2ModSounds->EmitSoundToAll(__VA_ARGS__) |
SOUND_EMIT_FROM_ENTITY(entity, ...) | g_pSource2ModSounds->EmitSoundFromEntity(entity, __VA_ARGS__) |
SOUND_STOP(guid) | g_pSource2ModSounds->StopSound(guid) |
HOOK_SOUND(handler) | g_pSource2ModSounds->HookSound(handler) |
UNHOOK_SOUND(handler) | g_pSource2ModSounds->UnhookSound(handler) |