local task = require "lib.utils.task" local ease = require "lib.utils.easing" local EFFECTS_SUPPORTED = love.audio.isEffectsSupported() --- @alias SourceFilter { type: "bandpass"|"highpass"|"lowpass", volume: number, highgain: number, lowgain: number } --- @class Audio --- @field musicVolume number --- @field soundVolume number --- @field looped boolean --- @field from love.Source? --- @field to love.Source? audio = {} audio.__index = audio --- здесь мы должны выгружать значения из файлика с сохранением настроек local function new(musicVolume, soundVolume) return setmetatable({ musicVolume = musicVolume, soundVolume = soundVolume, looped = true }, audio) end function audio:update(dt) if self.fader then local t = self.fader.value if self.from then self.from:setVolume(self.musicVolume * (1 - t)) end if self.to then self.to:setVolume(self.musicVolume * t) end end end --- if from is nil, than we have fade in to; --- if to is nil, than we have fade out from --- --- also we should guarantee, that from and to have the same volume --- @param from love.Source --- @param to love.Source --- @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 -- Reuse fader object to allow task cancellation if not self.fader then self.fader = { value = 0 } end 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 --- @param source love.Source --- @param settings SourceFilter? --- @param effectName string? function audio:play(source, settings, effectName) if source:getType() == "stream" then source:setLooping(self.looped) source:setVolume(self.musicVolume) source:play() else source:setVolume(self.soundVolume) source:play() end if settings and EFFECTS_SUPPORTED then source.setFilter(source, settings) end if effectName and EFFECTS_SUPPORTED then source:setEffect(effectName, true) end end function audio:setMusicVolume(volume) self.musicVolume = volume end function audio:setSoundVolume(volume) self.soundVolume = volume end return { new = new }