Skip to content

Client exports ​

Call these from a client script with exports.tm_sound:Name(...). Each name also works with the first letter's case flipped (destroy and Destroy).

A sound is identified by an id string you choose. Playing a new sound with an id that is already in use replaces the old one.

Playing ​

lua
exports.tm_sound:PlayUrl(id, url, volume?, loop?, options?)
exports.tm_sound:PlayUrlPos(id, url, volume?, position, loop?, options?)
exports.tm_sound:PlayOnEntity(id, url, volume?, netId, distance?, loop?, options?)
ParameterTypeDescription
idstringUnique name of the sound.
urlstringA web link, or a file path (see Sources).
volumenumber0.0 to 1.0, default 1.0.
positionvector3Where a positional sound plays.
netIdnumberNetwork id of the entity the sound follows.
distancenumberHow far it can be heard. Default is the Default distance setting.
loopbooleanRepeat until destroyed.
optionstableSee below.

PlayUrlPos follows xsound: the argument after the position is loop. The older form with distance in that place still works, because a number there is read as a distance. You can also pass the distance as options.distance.

lua
exports.tm_sound:PlayUrlPos('beacon', 'sounds/beep.ogg', 0.8, coords, true, { distance = 30.0 })
exports.tm_sound:PlayUrlPos('beacon', 'sounds/beep.ogg', 0.8, coords, 30.0, true)   -- same

Options ​

lua
{
    distance = 30.0,                      -- positional sounds, see above
    rate = 1.0,                           -- playback speed and pitch
    filter = { type = 'lowpass', frequency = 1000, Q = 1.0, gain = 0.0 },
    onPlayStart = function(info) end,     -- playback began
    onPlayEnd = function(info) end,       -- playback ended
    onLoading = function(info) end,       -- the audio is loading
    onError = function(info, err) end,    -- the audio could not be played
    onDestroy = function(info) end,       -- the sound was destroyed
}

Callbacks can also be added at any time with onPlayStart(id, fn), onPlayEnd, onLoading, onPlayPause, onPlayResume and onError.

Changing a sound ​

ExportDescription
Destroy(id)Stops the sound and frees it.
DestroyAll()Stops every sound.
Pause(id), Resume(id)Pause and resume.
setVolume(id, volume)Sets the volume. For a positional sound it sets its maximum, the distance falloff stays.
setVolumeMax(id, volume)Sets the maximum volume of a positional sound.
Position(id, position)Moves a positional sound.
Distance(id, distance)Changes how far it can be heard.
setSoundLoop(id, loop)Turns looping on or off.
setRate(id, rate)Playback speed and pitch, 1.0 is normal.
setTimeStamp(id, seconds)Seeks.
destroyOnFinish(id, bool)Whether the sound is removed when it ends. A looping sound never is.
setSoundDynamic(id, bool)Switches between positional and non positional.
setSoundURL(id, url)Swaps the audio and keeps every other setting.
repeatSound(id)Plays again from the start.
setFilter(id, filter)A biquad filter, or nil to remove it. Types: lowpass, highpass, bandpass, lowshelf, highshelf, peaking, notch, allpass.

EQ ​

lua
exports.tm_sound:setEQAll(id, low, mid, high)   -- gains in dB
exports.tm_sound:setEQ(id, 'low', -6)           -- one band: 'low', 'mid' or 'high'
exports.tm_sound:getEQ(id)                      -- { low, mid, high }

The bands are a low shelf at 320 Hz, a mid peak at 1 kHz and a high shelf at 3.2 kHz. 0 is flat, -40 silences the band. Gains are clamped to the Mixer limits settings. The EQ and filters need Web Audio, so web players such as YouTube store the values but do not play them.

Fades ​

lua
exports.tm_sound:fadeIn(id, durationMs, targetVolume?)   -- from silence to the target (default: the sound's volume)
exports.tm_sound:fadeOut(id, durationMs)                 -- to silence; the sound keeps playing, destroy it afterwards
exports.tm_sound:fadeTo(id, durationMs, targetVolume)    -- from the level it has now

A fade is one smooth ramp for every kind of sound. Setting the volume while a fade runs cancels it.

Information ​

ExportReturns
getInfo(id)The sound's info table, or nil.
soundExists(id)boolean
isPlaying(id), isPaused(id), isLooped(id), isDynamic(id)boolean
getLink(id)The url that was resolved for playback.
getPosition(id)vector3 or nil
getDistance(id), getVolume(id)number
getTimeStamp(id), getMaxDuration(id)Seconds, or -1 when the sound does not exist.
getAllAudioInfo()Every sound, by id.
isPlayerInStreamerMode()boolean
isPlayerCloseToAnySound()True when a positional sound is within its distance plus the Spatial buffer setting.

The info table holds id, url, volume, maxVolume, loop, dynamic, position, distance, playing, paused, entityId, rate, destroyOnFinish, timeStamp, maxDuration, filter and eq.

Entity sounds ​

PlayOnEntity attaches a sound to a networked entity. Each client follows the entity on its own: when it is outside a client's streaming range, that client holds the sound (keeping its pause and seek state) and starts it again at the correct point when the entity returns. Fast vehicles are extrapolated so the sound does not trail behind them.