How can I get a song's max playback loudness?

As @colbert2677 covered most of it already you might want to also look into CompressorSoundEffect as it works as a normalizer to keep a consistent volume level all the time for any sound.

If you’re absolutely set on the PlaybackLoudness for other uses as well you can try this out for a more consistent result:

local RunService = game:GetService("RunService")
local SoundService = game:GetService("SoundService")

local function MaxPlaybackLoudness(soundId, scrubTime, scanAmount)
	local ListPlaybackLoudness = {}
	local MaxPlaybackLoudness = 0
	local ScanSection = 0
	local ScanFinished = false
	
	local Sound = Instance.new("Sound")
	Sound.Parent = game.SoundService
	Sound.SoundId = soundId
	
	repeat RunService.Stepped:Wait() until Sound.IsLoaded

	print("Scrubbing soundId:", Sound.SoundId)
	local startTime = tick()
	
	for soundTime = 0, Sound.TimeLength, scanAmount do
		ScanSection = ScanSection + 1
		spawn(function()
			local scrubSound = Sound:Clone()
			local startScrub = tick()
			scrubSound.Parent = game.SoundService
			scrubSound.Volume = 0
			scrubSound:Play()
			scrubSound.TimePosition = soundTime
			local ScrubStep = RunService.Stepped:Connect(function()
				table.insert(ListPlaybackLoudness, scrubSound.PlaybackLoudness)
			end)
			repeat RunService.Stepped:Wait() 
			until (tick()-startScrub) > scrubTime
			ScrubStep:Disconnect()
			scrubSound:Stop()
			scrubSound:Destroy()
			scrubSound = nil
			if ScanSection >= soundTime then 
				ScanFinished = true 
			end
		end)
	end
	repeat RunService.Stepped:Wait() until ScanFinished
	Sound:Destroy()
	Sound = nil
	print("Completed scrubbing:", tick()-startTime)
	print("Peak audio loudness:", math.max(unpack(ListPlaybackLoudness)))
end

--[[MaxPlaybackLoudness
	soundId: audio id to fetch
	scrubTime: amount of seconds to record pbl for sound instance
	scanAmount: amount of seconds to create sound instance
]]--

MaxPlaybackLoudness("rbxassetid://203626633", 2, 2)
6 Likes

just do it slow, then print the loudest it gets. put this value in the sound so you can reach it.

1 Like

i have an idea hear me out

local sound = Instance.new("Sound", game:GetService("SoundService"))
local realVolume = 0.5
local realPlaybackSpeed = 1
local maxPlaybackLoudness = 0 -- don't change this, this'll be your result
sound.SoundId = "rbxassetid://insert_the_soundid" -- insert SoundId here
if not sound.IsLoaded then sound.Loaded:Wait() end -- wait for the thing to load

sound.PlaybackSpeed = 420000 -- lmao, i just took 420 seconds (7 minutes, aka the max audio length) and add 3 more zeros for good measure
sound.Volume = 0
local con1
sound.Ended:Once(function() -- idk, useless connections are not needed so
	con1:Disconnect()
end)
con1 = sound:GetPropertyChangedSignal("PlaybackLoudness"):Connect(function() -- Heartbeat definitely won't suffice, this sound finna go too fast
	if sound.PlaybackLoudness <= maxPlaybackLoudness then return end
	maxPlaybackLoudness = sound.PlaybackLoudness
end)
sound:Play() -- do the funny
task.wait() -- surely this will take less than a frame, i doubt supercomputers that can run at thousands of fps exist rn
sound.PlaybackSpeed = realPlaybackSpeed
sound.Volume = realVolume print(maxPlaybackLoudness)
-- now, you should have the maxPlaybackLoudness? i'm not too sure if this'll work but ig it's worth a shot

i later on saw this one.

should work better then my solution.

you could play the song at like 200 times speed and record the playbackloudness very quickly then play the song and use the recorded maxplaybackloudness

This post was from 4 years ago, some properties have probably been deprecated. Use sound.PlaybackLoudness to get the actual playback volume:

local RS = game:GetService("RunService")

local sound = workspace.Sound

local volumes = {}

sound.Played:Connect(function()
    
    local getVolume = RS.Heartbeat:Connect(function()
        print(tostring(math.floor(sound.PlaybackLoudness*10)/10).."dB")
        table.insert(volumes,sound.PlaybackLoudness)
    end)
    
    sound.Ended:Wait()
    getVolume:Disconnect()
    
    local total = 0
    for _,volume in pairs(volumes) do total += volume end
    
    local ranges = {math.huge,0}
    for _,volume in pairs(volumes) do
        if ranges[1] > volume then ranges[1] = volume end
        if ranges[2] < volume then ranges[2] = volume end
    end
    
    print("- - -")
    print("Average volume: "..tostring(total/#volumes).."dB")
    print("Lowest volume: "..tostring(ranges[1]).."dB")
    print("Highest volume: "..tostring(ranges[2]).."dB")
    
end)

Edit: I did just realise that sound.Amplitude doesn’t exist, as it’s actually sound.PlaybackLoudness.

wow they updated sound properties? This changes a lot thanks

I just re-read the sound properties and there is no sound.Amplitude