SoundService
A service that determines various aspects of how Sounds play in the game. SoundService is also often used to store SoundGroups although this is not mandatory for SoundGroups to work.
What can SoundService do?
SoundService properties such as SoundService.AmbientReverb, SoundService.DistanceFactor, SoundService.DopplerScale and SoundService.RolloffScale can be used to change how all Sounds play in the game.
The SoundService:SetListener() function allows developers to set the position where sounds are heard from.
SoundService:PlayLocalSound() can be used to play a sound locally regardless of where it is parented to.
Developers looking to find out more about how sound works in Roblox should consult the documentation provided for the FMOD sound engine.
Code Samples
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local SoundService = game:GetService("SoundService")
local localPlayer = Players.LocalPlayer
local reverbTags = {
["reverb_Cave"] = Enum.ReverbType.Cave,
}
-- collect parts and group them by tag
local parts = {}
for reverbTag, reverbType in pairs(reverbTags) do
for _, part in pairs(CollectionService:GetTagged(reverbTag)) do
parts[part] = reverbType
end
end
-- function to check if a position is within a part's extents
local function positionInPart(part, position)
local extents = part.Size / 2
local offset = part.CFrame:PointToObjectSpace(position)
return offset.x < extents.x and offset.y < extents.y and offset.z < extents.z
end
local reverbType = SoundService.AmbientReverb
while true do
task.wait()
if not localPlayer then
return
end
local character = localPlayer.Character
-- default to no reverb
local newReverbType = Enum.ReverbType.NoReverb
if character and character.PrimaryPart then
local position = character.PrimaryPart.Position
-- go through all the indexed parts
for part, type in pairs(parts) do
-- see if the character is within them
if positionInPart(part, position) then
-- if so, pick that reverb type
newReverbType = type
break
end
end
end
-- set the reverb type if it has changed
if newReverbType ~= reverbType then
SoundService.AmbientReverb = newReverbType
reverbType = newReverbType
end
end
local ServerScriptService = game:GetService("ServerScriptService")
local SoundService = game:GetService("SoundService")
-- Create custom plugin button
local toolbar = plugin:CreateToolbar("Empty Script Adder")
local newScriptButton = toolbar:CreateButton("Add Script", "Create an empty Script", "rbxassetid://1507949215")
local function playLocalSound(soundId)
local sound = Instance.new("Sound")
sound.SoundId = soundId
SoundService:PlayLocalSound(sound)
sound.Ended:Wait()
sound:Destroy()
end
local function onNewScriptButtonClicked()
-- Create new empty script
local newScript = Instance.new("Script")
newScript.Source = ""
newScript.Parent = ServerScriptService
playLocalSound("rbxassetid://0") -- Insert audio asset ID here
end
newScriptButton.Click:Connect(onNewScriptButtonClicked)
Summary
Properties
The ambient sound environment preset used by SoundService.
The number of studs to be considered a meter by SoundService when calculating 3D Sound volume attenuation.
This property determines the degree to which a 3D Sound object's pitch varies due to the Doppler effect.
Sets whether Sound playback from a client will replicate to the server.
Sets how fast 3D Sound volume attenuates, or 'rolls off'.
Methods
GetListener returns the current SoundService listener type and what is set as listener.
Plays a Sound locally, meaning the sound will only be heard by the client calling this function, regardless of where it's parented to.
Sets the listener for the SoundService.
Properties
AmbientReverb
The ambient sound environment preset used by SoundService.
The Enum.ReverbType this property simulates a range of different environment's impact on sound. Each different option corresponds with a preset available in the FMOD sound engine. For example, when AmbientReverb is set to Hangar, the sound will reverberate differently to simulate being in a large enclosed space.
Changing the AmbientReverb effects the following properties used by Roblox's sound engine.
- Reverberation decay time
- Initial reflection delay time
- Late reverberation delay time relative to initial reflection
- Reference high frequency
- High-frequency to mid-frequency decay time ratio
- Value that controls the echo density in the late reverberation decay
- Value that controls the modal density in the late reverberation decay
- Reference low frequency
- Relative room effect level at low frequencies
- Relative room effect level at high frequencies
- Early reflections level relative to room effect
- Room effect level at mid frequencies
Those interested in finding more out about ambient reverb presets should see the FMOD documentation on the topic. For most developers however, the Enum.ReverbType names are descriptive enough to be able to use this setting without advanced knowledge.
Code Samples
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local SoundService = game:GetService("SoundService")
local localPlayer = Players.LocalPlayer
local reverbTags = {
["reverb_Cave"] = Enum.ReverbType.Cave,
}
-- collect parts and group them by tag
local parts = {}
for reverbTag, reverbType in pairs(reverbTags) do
for _, part in pairs(CollectionService:GetTagged(reverbTag)) do
parts[part] = reverbType
end
end
-- function to check if a position is within a part's extents
local function positionInPart(part, position)
local extents = part.Size / 2
local offset = part.CFrame:PointToObjectSpace(position)
return offset.x < extents.x and offset.y < extents.y and offset.z < extents.z
end
local reverbType = SoundService.AmbientReverb
while true do
task.wait()
if not localPlayer then
return
end
local character = localPlayer.Character
-- default to no reverb
local newReverbType = Enum.ReverbType.NoReverb
if character and character.PrimaryPart then
local position = character.PrimaryPart.Position
-- go through all the indexed parts
for part, type in pairs(parts) do
-- see if the character is within them
if positionInPart(part, position) then
-- if so, pick that reverb type
newReverbType = type
break
end
end
end
-- set the reverb type if it has changed
if newReverbType ~= reverbType then
SoundService.AmbientReverb = newReverbType
reverbType = newReverbType
end
end
DefaultListenerLocation
DistanceFactor
The number of studs to be considered a meter by SoundService when calculating 3D Sound volume attenuation.
By default, the DistanceFactor is 3.33. This means, for the purposes of volume attenuation, a meter is considered 3.33 studs. The greater the DistanceFactor, the more gradually sound will attenuate.
local SoundService = game:GetService("SoundService")SoundService.DistanceFactor = 1 -- 1 meter = 1 studSoundService.DistanceFactor = 10 -- 1 meter = 10 studs
Developers are advised to only change this property if their game uses a different scale. For example, when using larger custom characters, developers may want to reduce the DistanceFactor. In all other cases, Sound settings such as Sound.RollOffMode should be used instead.
Those looking to find out more about how 3D sound in Roblox works, should consult the FMOD documentation.
DopplerScale
This property determines the degree to which a 3D Sound object's pitch varies due to the Doppler effect.
The Doppler effect describes a phenomenon whereby the pitch of a sound changes as the source and observer of the sound move further away, or closer together. The Doppler effect can often be seen in real life, such as when a car with a siren drives past.
Increasing this value exaggerates the impact of the Doppler effect, whereas decreasing it minimizes it. By default, the value of this property is 1.
local SoundService = game:GetService("SoundService")SoundService.DopplerScale = 1 -- defaultSoundService.DopplerScale = 2 -- exaggerated Doppler effectSoundService.DopplerEffect = 0.5 -- subdued Doppler effect
Note the Doppler effect has no impact on 2D Sounds, (Sounds not parented to a BasePart or Attachment).
Developers wishing to learn more about the different settings Roblox's sound engine uses should consult the FMOD documentation.
RespectFilteringEnabled
The RespectFilteringEnabled property determines whether Sound playback is replicated from the client to the server, and therefore from server. In other words, when a LocalScript calls Sound:Play() and this property is true, the sound will only play on the respective client. If the property is false, other clients will also hear the sound.
RolloffScale
Sets how fast 3D Sound volume attenuates, or 'rolls off'.
Note, this property only applies to Sounds whose Sound.RollOffMode property is set to 'Inverse' or 'InverseTapered'. 'Linear' and 'LinearSquare' Enum.RollOffMode use a different attenuation model which is not influenced by this property. This property also has no impact on 2D sounds (Sounds not parented to a BasePart or Attachment).
The higher the RolloffScale, the more rapidly a 3D sound's volume will attenuate as the distance between the listener and the sound increases.
By default the roll off scale is set to 1, which simulates the real world.
local SoundService = game:GetService("SoundService")SoundService.RolloffScale = 1 -- attenuation simulates real worldSoundService.RolloffScale = 2 -- sound attenuates twice as fast as the real world
Developers wishing to learn more about the different settings Roblox's sound engine uses should consult the FMOD documentation.
VolumetricAudio
Methods
GetListener
This function returns the SoundService current listener type and what is set as listener.
The first result returned is the Enum.ListenerType of the listener, the second result is dependent on the ListenerType:
ListenerType | Description |
---|---|
Enum.ListenerType.Camera | Does not return a listener object as Workspace/CurrentCamera is always used |
Enum.ListenerType.CFrame | Returns the CFrame used in SoundService:SetListener() |
Enum.ListenerType.ObjectPosition | Returns the BasePart used in SoundService:SetListener() |
Enum.ListenerType.ObjectCFrame | Returns the BasePart used in SoundService:SetListener() |
The listener can be changed using SoundService:SetListener().
local SoundService = game:GetService("SoundService")SoundService:SetListener(Enum.ListenerType.CFrame, CFrame.new(0, 0, 0))local listenerType, listener = SoundService:GetListener()print(listenerType, listener)
What is a listener?
The listener determines the point from which audio in the game is being 'heard' by the player. For 3D Sounds (Sounds parented to a BasePart or Attachment) the listener influences the volume and left/right balance of a playing sound. Listeners have no influence on the playback of 2D sounds as they have no position of emission.
By default, the listener is set to the CurrentCamera. However, a range of different types of listeners can be used.
Returns
The current Enum.ListenerType and what the listener has been set to. Dependent on Enum.ListenerType the listener could be a BasePart, a CFrame or nil.
OpenAttenuationCurveEditor
Parameters
Returns
OpenDirectionalCurveEditor
Parameters
Returns
PlayLocalSound
Plays a Sound locally, meaning the sound will only be heard by the client calling this function, regardless of where it's parented to. This function is most useful for playing a Sound locally in the Studio client, for instance in a Script for a Plugin.
Parameters
Returns
Code Samples
local ServerScriptService = game:GetService("ServerScriptService")
local SoundService = game:GetService("SoundService")
-- Create custom plugin button
local toolbar = plugin:CreateToolbar("Empty Script Adder")
local newScriptButton = toolbar:CreateButton("Add Script", "Create an empty Script", "rbxassetid://1507949215")
local function playLocalSound(soundId)
local sound = Instance.new("Sound")
sound.SoundId = soundId
SoundService:PlayLocalSound(sound)
sound.Ended:Wait()
sound:Destroy()
end
local function onNewScriptButtonClicked()
-- Create new empty script
local newScript = Instance.new("Script")
newScript.Source = ""
newScript.Parent = ServerScriptService
playLocalSound("rbxassetid://0") -- Insert audio asset ID here
end
newScriptButton.Click:Connect(onNewScriptButtonClicked)
SetListener
Sets the listener used by the client.
The first parameter is the Enum.ListenerType of the listener, the second parameter is dependent on the listener type.
- Camera ListenerType - Does not return a listener object as Workspace.CurrentCamera is always used
- CFrame ListenerType - The CFrame to be used
- ObjectPosition ListenerType - The BasePart to be used
- ObjectCFrame ListenerType - The BasePart to be used
The listener can be retrieved using SoundService:GetListener():
local SoundService = game:GetService("SoundService")SoundService:SetListener(Enum.ListenerType.CFrame, CFrame.new(0, 0, 0))local listenerType, listener = SoundService:GetListener()print(listenerType, listener)
What is a listener?
The SoundService listener determines the point from which audio in the game is being 'heard' by the player. For 3D Sounds (sounds parented to a BasePart or Attachment) the listener influences the volume and left/right balance of a playing sound. Listeners have no influence on the playback of 2D sounds as they have no position of emission.
By default, the listener is set to the CurrentCamera. However, a range of different types of listeners can be used.
Parameters
The Enum.ListenerType of the listener.
Dependent on the Enum.ListenerType. BasePart for 'ObjectPosition' or 'ObjectCFrame', CFrame for 'CFrame', nil for 'Camera'.