Audio Visualizer Bars

Yet another mystifying creation from boat bomber. I don’t think roblox allow us to read sound data. I guess it’s time to check the code.

Thank you for your continuous contribution to roblox’s open source community <3

3 Likes

Bump, sorry.

I just came across this, but I’m having an issue. I created the GUI, that’s fine. I parented it to the Frame, which is ALSO fine.

Whenever I try linking the audio, it just tells me it’s a nil value, which is super vague and makes no sense at all.

local VisualBrains = require(script.Parent.Visualizer)

local Caleb = workspace.WorkspaceScripts:WaitForChild("MusicList").Audio1

local ActualVisualizer = VisualBrains.new(script.Parent, 80)

VisualBrains:LinkToSound(Caleb)

tried it on a caleb belkin song, all it does is throw that “attempt to call a nil value” line.

Cuz you did VisualBrains:Link when you meant to do ActualVisualizer:Link! You’re attempting to call a nil value since that function doesn’t exist there- it exists on the visualizer object.

Tysm! I didn’t even know that it worked that way, I guess I went over documentation a little too fast.

Now that we’re on the topic of playing, would it be possible to assign :LinkToSound() on multiple sounds at once so I can make it display the visualizer for multiple different Sound instances? If so would a if I, v in pairs loop work just fine? I also got the nil value error while doing that but I’m going to assume it was simply the error you have corrected here

*Worded this weirdly…

What I mean by show multiple different Sound instances, is when 1 is done playing, then the next completely separate sound then displays it’s link to sound

Just link the next sound when the first one finishes playing, you can swap between sounds by calling Link on the new one. Visualizers aren’t stuck with the first sound you link, you can hotswap them.
Please read the post, it shows all of this.

1 Like

Oh sorry, I made it seem like I hadn’t read the post, I just wanted to know if it mattered if I made all link at once and it’d change accordingly to each song. This makes sense now, and I do have a proper way of doing this. Much appreciated.

1 Like

I love it I hope to use it sometime.

Another issue I’ve encountered, is that it works in Studio, but not in the actual Roblox Game.

I have solutions I want to attempt, but if you could possibly tell me if there is something I need to do first for SurfaceGuis that’d be awesome, ty.

Edit

It appears my solutions for :WaitForChild() and adding extra wait time didn’t do anything. The visualizer gets created, but doesn’t sync with the music even though I did link it with the sound.

I know this because it works in studio, but not the real Roblox Game.

Show your code please because there’s no way for anyone to debug your mistakes if we cant see them.

I will get that for you right now, and I will update this message when I got it ready. The codes long, so I will shorten it to represent what the rest of the script looks like

local VisualBrains = require(workspace.JukeVibe.Sign.SurfaceGui.SongFrame.Visualizer:WaitForChild("Visualizer"))

local ActualVisualizer = VisualBrains.new(workspace.JukeVibe.Sign.SurfaceGui.SongFrame.Visualizer, 25)

local SongBool = workspace.WorkspaceScripts:WaitForChild("MusicList")

while true do
	wait(10) -- waits 10 seconds giving leisure time for songs to load
	script.Parent.Audio1:Play() -- Play the song
ActualVisualizer:LinkToSound(SongBool.Audio1) -- Link to the song so it displays the Visualizer
	game.workspace.JukeVibe.Sign.SurfaceGui.SongFrame.Song.Text = "Caleb Belkin - Life" -- This is to display text on a sign in game.
	wait(script.Parent.Audio1.TimeLength) -- Waits the entire songs length until waiting 5 seconds next.
	wait(5) -- Usually it will wait 5 extra seconds until playing the next song
end -- The code doesn't usually end here, I just shortened it because the code repeats with different things. Not the most idle code, but it's worked fine and I don't know any other way.

This code works in studio as stated, but not in the real game.

Please include a screenshot of your workspace because your code makes it extremely unclear. You index Audio1 in multiple different ways…

Are you using a LocalScript that’s parented somewhere inside workspace? That doesn’t work.

Also, that whole thing is just really poor practice and not the right way to do it. You’re essentially writing out an entire loop’s behavior by hand. Not to mention using wait() instead of events.

local Visualizer = require(workspace.JukeVibe.Sign.SurfaceGui.SongFrame.Visualizer:WaitForChild("Visualizer"))
local SongVisualizer = Visualizer.new(workspace.JukeVibe.Sign.SurfaceGui.SongFrame.Visualizer, 25)

-- I assume SongBool is a folder of Sound objects?
local SongBool = workspace.WorkspaceScripts:WaitForChild("MusicList")

-- Make them automatically link to the visualizer when they play
for _,Song in ipairs(SongBool:GetChildren()) do
	if not Song:IsA("Sound") then continue end
	
	Song.Played:Connect(function()
		SongVisualizer:LinkToSound(Song)
	end)
end

-- Store the titles of each audio in a dictionary
local audioTitles = {
	Audio1 = "Caleb Belkin - Life";
}

-- Continuously go through all the songs, playing them
wait(10) -- Load time
while true do
	
	for _,Song in ipairs(SongBool:GetChildren()) do
		if not Song:IsA("Sound") then continue end

		game.workspace.JukeVibe.Sign.SurfaceGui.SongFrame.Song.Text = audioTitles[Song.Name]
		Song:Play()
		Song.Ended:Wait()  -- Properly waits for the song to end instead of using wait()
		
		wait(0.5) -- Time between songs
	end
end 
1 Like

I keep all my sounds located right here:
I am NOT using any local scripts for this. I was hesitant at first, but I stuck with a Server Script because I felt like that was more practical (in this case it was)

Right here is where I have my frame setup including the module itself

image

These 2 screenshots are the only things I’m messing with (ik theres a lot of sounds.)

Oh also I appreciate the code fix up. At the time I didn’t know much about how to make a sound system and I made that before I was ever introduced to in pairs() ipairs() systems.

Your code works fine, but the visualizer still does not show according to the music even without my old and messy spaghetti code.

On top of that, it will skip 8 songs after the first song, and then play the play list like normal, which then completely breaks some songs after. My game has slow loading for players sometimes so could this be the cause? I’m lost, for realzies.

I appreciate the time and effort put into my questions. I will attempt to troubleshoot further, but I’ll be looking for other options as well. :+1:

the PlaybackLoudness property doesn’t replicate across the client server barrier, which is probably why it only works in Studio. you have to use a LocalScript in order to tell how loud an audio is at any given point in time

1 Like

I have a bit of information to add, not sure if I’ve already mentioned this though: It doesn’t work when you play test with a character in studio, but works without a character play test (this is known as “Run” as everyone is familiar with, which is indeed server sided).

If what you were saying is true, wouldn’t it work with the character play test? Even when I check the server sided part of the game it still shows nothing. Only seems to break when there is players.

Also I wouldn’t know how to associate boatbombers API with what you’re saying.

it makes sense for it to stop working when you do a normal Play Solo as opposed to Run actually, ever since Roblox released Accurate Play Solo which seperated both the client and the server when you do a playtest. when you use “Run”, it’s likely that it behaves more like how it did before, with the client and server technically being the same thing-- causing the infamous “it worked in studio, but not in-game” bugs.

also, this module very likely relies on Sound.PlaybackLoudness, a property that tells you the current amplitude of any given sound. it uses this to create the animated bars. on the client, this should work perfectly fine-- however on the server, this will always return zero, so you may see the bar objects being created on the server, but they’ll always be the same height due to the fact that the server has no idea how loud an audio actually is at all.

if you want this to work correctly, I would probably find a way to call the module in a LocalScript instead. it’s very likely that you’ll need to seperate your server’s jukebox logic and the client’s visualizer logic.

2 Likes

why is my script not working

local sounder = require(script:WaitForChild("Visualizer"))

sounder.new(script.Parent.Frame,200)
sounder:LinkToSound(script.Parent.Music)

script:WaitForChild("Music"):Play()

the error is in line 4 where i link to music and i get error attempt to call nil value

Haven’t used this module, but try this:

local sounder = require(script:WaitForChild("Visualizer"))

local visualizer = sounder.new(script.Parent.Frame,200)
visualizer:LinkToSound(script.Parent.Music)

script:WaitForChild("Music"):Play()
1 Like

thanks it worked! thanks so much again