I have made a speaker system with multiple speakers and multiple audio sounds coming from those speakers. I use for, iv pairs in order to manage the sound and to play the sound.
But for some reason, whenever I start playing the song, the sound has this unpleasant delay which just makes it noisy and not very nice to hear. I’m not sure if this is a Roblox bug or if I scripted something wrong, but I have recorded the video just to show as an example.
I haven’t really added any echo sound effects to the audio, I just added some reverb to make it more realistic but other than that, I do not really know what the cause of this echo is. I just want to make it so it could all start playing at the same/approximately the same time.
If anybody has any ways or ideas to fix this, please let me know.
Check the Sound Properties when you have the Sound selected. Click the Play button in Properties and see if the sound starts instantly, or has a built in pause. If it pauses, then you need to change the time the music starts at.
I think your big issue here is that if you have the sound playing from multiple Parts then it’s going to be slightly out of synch. Just like in real life, if you have 2 speakers 332 meters apart and are standing right next to one of them, then the sound from the second one is going to reach you 1 second later than the sound from the first one.
I get where you’re coming from and it is a reasonable theory, but let’s say I have a sound that is already preloaded into the game (like i add a audio with a soundID already in from the studio, instead of putting it in through the gui), it doesn’t echo at all. I believed that maybe it is an issue with the sounds loading in faster than each other, but even if so, I don’t really know how to prevent that or fix it.
And also, even if the sound may have a pause, it should still sound the same for every speaker because it all should start at the same time. Maybe I misunderstood on what you are trying to say but I just wanted to say that.
Always pre-load sounds into your game before using them for the best results.
I think if you try using the sound as you load it into each speaker it will take a different amount of time before each speaker gets the sound and plays it.
Can’t you get the GUI to load the sound into your game, then after it’s successfully loaded then play it through all the speakers using that single source?
I actually haven’t thought of that, as the for, iv loops through every sound, putting the ID in and then immediately makes the sound play, it could possibly defer how synced the sound is to one another.
My GUI works as is: You input a sound id into the textbox, and when you press “Submit”, it sends whatever is in the textbox from a Local Script, to a RemoteFunction. (I’m using remotefunction as I am planning to return info if the ID is valid)
And then there is another script that receives all of this information, and then runs a for, iv loop to start playing the sound and other functions etc.
As I am quite new to scripting, I am wondering how would I pre-load sounds into the game before playing them?
you can yield the sounds until all sounds are loaded by:
--in for loop at the end of each iteration
if not sound.IsLoaded then
sound.IsLoaded:Wait()
end
--outside the for loop, loop through all sounds again and play as they are all loaded
Or you could just play it globally.
Or now you can put the sound in 1 Transparent/CanCollide Part that surrounds the area with all the speakers in it.
Or you could just wait a couple seconds after the sound is loaded into all the speakers, then run another for i,v loop to play them. That shouldn’t be much of a delay.
Either that or make each speaker fade out and then in as you go from one speaker area to another.
So I have tried inserting your script and trying it out, but for some reason this error keeps popping up and it doesn’t really make any sense for me.
My script is
local speakers = script.Parent.Parent.Parent.Parent.Speakers_and_Intercoms:GetDescendants()
local information = script.Parent.Parent
script.Parent.OnServerInvoke = function(player,music)
if information.Submitted.Value == false then
for i,v in pairs(speakers) do
if v.Name == "Speaker" then
v.SoundId = "rbxassetid://"..music
if not v.IsLoaded then
v.IsLoaded:Wait()
end
end
if v.Name == "Speaker" then
information.Submitted.Value = true
v:Play()
end
end
end
I think part of the issue is that your script looks like it’s running through Speakers_and_Intercoms:GetDescendants() each time it goes through your i,v loop. If you have a load of Parts in that model that may cause a delay, or if one of the items is a boolean then it would cause an issue on line 11.
You are loading the sound within the loop so every time it checks to see if the Part is named "Speaker" it reloads the sound.
How about:
local speakers = script.Parent.Parent.Parent.Parent.Speakers_and_Intercoms:GetDescendants()
local information = script.Parent.Parent
script.Parent.OnServerInvoke = function(player,music)
local musicSound = "rbxassetid://"..music --only load it once
if not v.IsLoaded then --not sure if a WaitForChild would work better here
v.IsLoaded:Wait()
end
if information.Submitted.Value == false then
for i,v in pairs(speakers) do
if v.Name == "Speaker" then
v.SoundId = musicSound
information.Submitted.Value = true
v:Play()
end
end
end
end
if information.Submitted.Value then return end
for _,v in pairs(speakers) do v.SoundId = musicSound
if not v.IsLoaded then v.Loaded:Wait()
end end
for i,v in pairs(speakers) do
if v.Name == "Speaker" then
information.Submitted.Value = true
v:Play()
end
end