I may be a bit off here but, from working with many languages there is a unwritten rule more or less not to call 0 time waits … wait(), wait(0) or the task.wait version. Roblox uses this in some templates so I assume your 0 time calls are not truly 0 time. If I need to go low, I will always use 0.33 or even 0.033. these are old assembler tricks on faking one FPS wait. The fact you are finding a 0 wait not consistent isn’t shocking. Many languages would just lock up with a call like that.
Edit: It would be interesting to see your test using this technique. I got a feeling it will pass with flying colors with a task.wait …
Like this? The wording was a little confusing.
Either way, the issue persists.
local SoundService = game:GetService("SoundService")
local Samples = SoundService.Samples
local offset
while true do
local c = Samples.loop_mika:Clone()
c.Parent = Samples
c:Play() -- doesnt seem to make a difference if its before or after
if not c.IsLoaded then c.Loaded:Wait() end
local nextOffset = c.TimePosition
print(nextOffset) -- still returns 0
if offset then c.TimePosition += offset end
task.wait(math.max(0.5 - nextOffset, 0))
offset = nextOffset
end
Removing the 0 waits doesn’t seem to change anything.
local SoundService = game:GetService("SoundService")
local Samples = SoundService.Samples
local expectedInterval = 0.5
local lastTime = tick()
while true do
local currentTime = tick()
local elapsedTime = currentTime - lastTime
lastTime = currentTime
local waitTime = expectedInterval - elapsedTime
lastElapsed = (waitTime > 0 and task.wait(waitTime) or 0.5)
local c = Samples.loop_mika:Clone()
c.Parent = SoundService
c:Destroy()
end
If you read the documentation, task.wait will wait until the heartbeat after the time is up. It also says that task.wait() will default to task.wait(0) and that it is equivalent to RunService.Heartbeat:Wait()
Yes. In the top post, I was asking for any possible alternatives to task.wait, or any way to mitigate its desync well enough, to where it doesn’t sound awful.
I didn’t say remove it. Anyways you’re using this to find an expectedInterval/elapsedTime. Why do that when you can just read the real position of the music being played.
Because it is being destroyed in that code example.
Using an alternative version where it isn’t being destroyed, the result (unless I did it wrong) is also the same issue.
local SoundService = game:GetService("SoundService")
local Samples = SoundService.Samples
local offset
while true do
local c = Samples.loop_mika:Clone()
c.Name = "-"
c.Parent = Samples
c:Play()
if not c.IsLoaded then c.Loaded:Wait() end
local nextOffset = c.TimePosition
print(nextOffset)
if offset then c.TimePosition += offset end
local calc = 0.5 - nextOffset
if calc > 0 then task.wait(calc) end
offset = nextOffset
end
I was just pointing out, I could see how a wait(0) could be inconstant. There is no such a call … It’s like dividing by 0 … one of the things you just don’t do in a program or it crashes.
Going with your post … how does this work out?
local SoundService = game:GetService("SoundService")
local RunService = game:GetService("RunService")
local Samples = SoundService.Samples
local expectedInterval = 0.5
local lastTime = tick()
local function createSound()
local c = Samples.loop_mika:Clone()
c.Parent = Samples
c:Play()
lastTime = tick()
end
RunService.Heartbeat:Connect(function()
if tick() - lastTime >= expectedInterval then
createSound()
end
end)
createSound()
Sounds are unreliable, make sure they’re completely loaded before playing
you can use a while true do loop to check if enough time has passed constantly, and it runs faster than task.wait(). The loop will unfortunately unintentionally cap FPS unless you use a parallel desynchronized thread, however using that may bring on another onset of delay issues.
Perhaps the Roblox engine simply isn’t cut for the job.
It is very inconsistent for my use case, as humans are much more perceptive to minor differences in audio delay, than most other things, which is why this issue even exists, and has no already known solution in sight. It’s a very niche use.
local SoundService = game:GetService("SoundService")
local TweenService = game:GetService("TweenService")
local Samples = SoundService.Samples
local expectedInterval = 0.5
local function createSound()
local c = Samples.loop_mika:Clone()
c.Parent = Samples
c:Play()
local tweenInfo = TweenInfo.new(expectedInterval)
local tween = TweenService:Create(c, tweenInfo, {})
tween:Play()
tween.Completed:Connect(function()
createSound()
end)
end
createSound()
Actually, wait() with negative numbers works. I just tried it and it says it on the documentation. task.wait doesn’t. It went back in time 2 seconds when I did wait(-2).
You could actually experiment with the exact same setup yourself, as I’ve linked the original audio file for download above (since we’re already clogging up the thread replies fairly quickly):