From 00f1c7f7ee03ca5fda7d5615a04871882cbd45d2 Mon Sep 17 00:00:00 2001 From: Kitsune-Jesus Date: Sun, 8 Feb 2026 04:33:13 +0100 Subject: [PATCH] fix(audio): remove duplicated logic and fix fader lifecycle in crossfade --- lib/audio.lua | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/lib/audio.lua b/lib/audio.lua index f6fa637..465f72a 100644 --- a/lib/audio.lua +++ b/lib/audio.lua @@ -40,42 +40,31 @@ end --- @param ms number? in milliseconds function audio:crossfade(from, to, ms) print("[Audio]: Triggered crossfade") + + -- Stop previous 'from' if it's dangling to avoid leaks + if self.from and self.from ~= from and self.from ~= to then + self.from:stop() + end + self:play(to) to:setVolume(0) self.from = from self.to = to - -- Using a dummy object to tween a value from 0 to 1 - local fade = { value = 0 } + -- Reuse fader object to allow task cancellation + if not self.fader then self.fader = { value = 0 } end + self.fader.value = 0 - task.tween(fade, { value = 1 }, ms or 1000, ease.easeOutCubic)(function() - self.from:setVolume(0) - self.to:setVolume(self.musicVolume) - self.from:stop() - print("[Audio]: Crossfade done") - end) - - -- We need a custom update loop for the volume during the tween - -- Since task.tween updates properties, we can use a "monitor" task or just rely on `update` if we expose the task? - -- Actually, task.tween updates `fade.value` every frame. - -- We need to apply this value to the audio sources every frame. - -- BUT task.tween doesn't provide an "onUpdate" callback easily. - -- Workaround: create a task that runs every frame? Or modify task.tween? - - -- Let's check task.lua... it updates properties on the target object. - -- So `fade.value` will change. We need to apply it. - -- We can hook into `update` or use a metatable on `fade`? - - -- Let's use a "reactive" table with metatable setters? Overkill. - -- Simplest way: Add `onUpdate` to task.tween or just use `audio:update` to poll `fade.value`? - -- But `fade` is local. - - -- Better approach: Tween `self` properties? No, volume is on Source userdate. - -- Let's add a `fader` object to `self` that we tween, and in `update` we apply it. - - self.fader = { value = 0 } task.tween(self.fader, { value = 1 }, ms or 1000, ease.easeOutCubic)(function() + if self.from then + self.from:setVolume(0) + self.from:stop() + end + if self.to then + self.to:setVolume(self.musicVolume) + end self.fader = nil + print("[Audio]: Crossfade done") end) end