MTA.Castiel Posted January 28, 2022 Share Posted January 28, 2022 Hi there. Below is a simple client-side code that allows us to play a song by command. For our stopMusic function I've made an array of setTimer's to bring down the volume before stopping the song completely, thus achieving a fadeout effect. It works alright but i feel like there must be a much cleaner or simplified way of doing this: Which would be the best? function playMusic() song = playSound("music/track_05.mp3", true) setSoundVolume(song, 1) end addCommandHandler("pmusic", playMusic) function stopMusic() setTimer(function() if isElement(song) then setSoundVolume(song, 0.95) end end, 100, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.90) end end, 200, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.85) end end, 300, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.80) end end, 400, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.75) end end, 500, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.70) end end, 600, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.65) end end, 700, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.60) end end, 800, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.55) end end, 900, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.50) end end, 1000, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.45) end end, 1100, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.40) end end, 1200, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.35) end end, 1300, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.30) end end, 1400, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.25) end end, 1500, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.20) end end, 1600, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.15) end end, 1700, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.10) end end, 1800, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.09) end end, 1900, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.08) end end, 2000, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.07) end end, 2100, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.06) end end, 2200, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.05) end end, 2300, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.04) end end, 2400, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.03) end end, 2500, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.02) end end, 2600, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.01) end end, 2700, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0) end end, 2800, 1) setTimer(function() if isElement(song) then --Destroy the sound element destroyElement(song) end end, 2900, 1) end addCommandHandler("smusic", stopMusic) Link to comment
TMTMTL Posted January 29, 2022 Share Posted January 29, 2022 Hi. I'm on my phone at the moment so it's a bit awkward. But you could make this a lot cleaner by making the volume a variable and only using 1 timer. Local soundVolume = 1 at the top, set your timer to 100 * 10, put if soundVolume > 0 then soundVolume = soundVolume - 0.1 end above the playSound, and set the Volume argument to the soundVolume variable. 1 Link to comment
Scripting Moderators ds1-e Posted January 29, 2022 Scripting Moderators Share Posted January 29, 2022 20 hours ago, MTA.Castiel said: Hi there. Below is a simple client-side code that allows us to play a song by command. For our stopMusic function I've made an array of setTimer's to bring down the volume before stopping the song completely, thus achieving a fadeout effect. It works alright but i feel like there must be a much cleaner or simplified way of doing this: Which would be the best? function playMusic() song = playSound("music/track_05.mp3", true) setSoundVolume(song, 1) end addCommandHandler("pmusic", playMusic) function stopMusic() setTimer(function() if isElement(song) then setSoundVolume(song, 0.95) end end, 100, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.90) end end, 200, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.85) end end, 300, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.80) end end, 400, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.75) end end, 500, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.70) end end, 600, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.65) end end, 700, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.60) end end, 800, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.55) end end, 900, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.50) end end, 1000, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.45) end end, 1100, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.40) end end, 1200, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.35) end end, 1300, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.30) end end, 1400, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.25) end end, 1500, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.20) end end, 1600, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.15) end end, 1700, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.10) end end, 1800, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.09) end end, 1900, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.08) end end, 2000, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.07) end end, 2100, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.06) end end, 2200, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.05) end end, 2300, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.04) end end, 2400, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.03) end end, 2500, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.02) end end, 2600, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0.01) end end, 2700, 1) setTimer(function() if isElement(song) then setSoundVolume(song, 0) end end, 2800, 1) setTimer(function() if isElement(song) then --Destroy the sound element destroyElement(song) end end, 2900, 1) end addCommandHandler("smusic", stopMusic) You can use https://wiki.multitheftauto.com/wiki/Animate In order to smoothly change volume. 1 Link to comment
MTA.Castiel Posted January 31, 2022 Author Share Posted January 31, 2022 @TheManTheMythTheLegend I don't really understand how your method is suppose to work, here's what I've followed on: local soundVolume = 1 function playMusic() if soundVolume > 0 then soundVolume = soundVolume - 0.1 end song = playSound("music/track.mp3", true) setSoundVolume(song, soundVolume) end addCommandHandler("pmusic", playMusic) function stopMusic() setTimer(function() if isElement(song) then destroyElement(song) end end, 100*10, 1 ) end addCommandHandler("smusic", stopMusic) Link to comment
TMTMTL Posted January 31, 2022 Share Posted January 31, 2022 I see where you've got confused. Give me an hour as I've just woken, I'll post an example. Link to comment
TMTMTL Posted January 31, 2022 Share Posted January 31, 2022 local soundVolume = 1 function playMusic() song = playSound("music/track.mp3", true) setSoundVolume(song, soundVolume) setTimer(fadeSound, 100, 10) end addCommandHandler("pmusic", playMusic) function fadeSound() if soundVolume > 0 then soundVolume = soundVolume - 0.1 setSoundVolume(song, soundVolume) else destroyElement(song) end end addCommandHandler("smusic", fadeSound) Untested but this should do the trick. Link to comment
MTA.Castiel Posted January 31, 2022 Author Share Posted January 31, 2022 Alright so there's a fade now and it's quite short, also the fade starts as soon as the song starts then stays silent, I don't think the setTimer for the fadeSound belongs within the playMusic function Link to comment
TMTMTL Posted January 31, 2022 Share Posted January 31, 2022 7 minutes ago, MTA.Castiel said: Alright so there's a fade now and it's quite short, also the fade starts as soon as the song starts then stays silent, I don't think the setTimer for the fadeSound belongs within the playMusic function I did say it was untested. Well the barebones of how to do it are there, and you are along the right lines. Now have your own attempt at resolving it. You asked for help, I won't write the script for you Link to comment
βurak Posted January 31, 2022 Share Posted January 31, 2022 (edited) hi i have tested the animate function for you you can test the example i made here but i am not sure if this is what you want local test = playSound("music.wav", true) setSoundVolume(test, 1.0) local anims, builtins = {}, {"Linear", "InQuad", "OutQuad", "InOutQuad", "OutInQuad", "InElastic", "OutElastic", "InOutElastic", "OutInElastic", "InBack", "OutBack", "InOutBack", "OutInBack", "InBounce", "OutBounce", "InOutBounce", "OutInBounce", "SineCurve", "CosineCurve"} function table.find(t, v) for k, a in ipairs(t) do if a == v then return k end end return false end function animate(f, t, easing, duration, onChange, onEnd) assert(type(f) == "number", "Bad argument @ 'animate' [expected number at argument 1, got "..type(f).."]") assert(type(t) == "number", "Bad argument @ 'animate' [expected number at argument 2, got "..type(t).."]") assert(type(easing) == "string" or (type(easing) == "number" and (easing >= 1 or easing <= #builtins)), "Bad argument @ 'animate' [Invalid easing at argument 3]") assert(type(duration) == "number", "Bad argument @ 'animate' [expected number at argument 4, got "..type(duration).."]") assert(type(onChange) == "function", "Bad argument @ 'animate' [expected function at argument 5, got "..type(onChange).."]") table.insert(anims, {from = f, to = t, easing = table.find(builtins, easing) and easing or builtins[easing], duration = duration, start = getTickCount( ), onChange = onChange, onEnd = onEnd}) return #anims end function destroyAnimation(a) if anims[a] then table.remove(anims, a) end end addEventHandler("onClientRender", root, function( ) local now = getTickCount( ) for k,v in ipairs(anims) do v.onChange(interpolateBetween(v.from, 0, 0, v.to, 0, 0, (now - v.start) / v.duration, v.easing)) if now >= v.start+v.duration then if type(v.onEnd) == "function" then v.onEnd( ) end table.remove(anims, k) end end end) function fadeOutSound(sound, fadeTime) animate(1.0, 0, 1, fadeTime, function(volumeValue) setSoundVolume(sound, volumeValue) if(sound and getSoundVolume(sound) == 0) then stopSound(sound) end end) end addCommandHandler("fadesound", function() fadeOutSound(test, 3000) -- Completely mute in 3 seconds end) Edited January 31, 2022 by Burak5312 1 Link to comment
Hydra Posted January 31, 2022 Share Posted January 31, 2022 Why don't you use this to stop the sound slowly: l function stopSoundSlowly (sElement) if not isElement(sElement) then return false end local sound_timer_quant = getSoundVolume(sElement) local slowlyStop = setTimer( function () local soundVolume = getSoundVolume(sElement) setSoundVolume(sElement,soundVolume - 0.5) if soundVolume >= 0 then stopSound(sElement) end end,400,sound_timer_quant*2 ) end https://wiki.multitheftauto.com/wiki/StopSoundSlowly You can also make something like startSoundSlowly with this function Link to comment
MTA.Castiel Posted February 1, 2022 Author Share Posted February 1, 2022 @Burak5312 Although the code looks more a bit more than my array of setTimers Your method on fading sound using the Animate function really helped a lot. I didn't actually know about it since Srslyyyy quoted it, but it was great working from this example thanks man i appreciate it local test = playSound("music.wav", true) setSoundVolume(test, 1.0) local anims, builtins = {}, {"Linear", "InQuad", "OutQuad", "InOutQuad", "OutInQuad", "InElastic", "OutElastic", "InOutElastic", "OutInElastic", "InBack", "OutBack", "InOutBack", "OutInBack", "InBounce", "OutBounce", "InOutBounce", "OutInBounce", "SineCurve", "CosineCurve"} function table.find(t, v) for k, a in ipairs(t) do if a == v then return k end end return false end function animate(f, t, easing, duration, onChange, onEnd) assert(type(f) == "number", "Bad argument @ 'animate' [expected number at argument 1, got "..type(f).."]") assert(type(t) == "number", "Bad argument @ 'animate' [expected number at argument 2, got "..type(t).."]") assert(type(easing) == "string" or (type(easing) == "number" and (easing >= 1 or easing <= #builtins)), "Bad argument @ 'animate' [Invalid easing at argument 3]") assert(type(duration) == "number", "Bad argument @ 'animate' [expected number at argument 4, got "..type(duration).."]") assert(type(onChange) == "function", "Bad argument @ 'animate' [expected function at argument 5, got "..type(onChange).."]") table.insert(anims, {from = f, to = t, easing = table.find(builtins, easing) and easing or builtins[easing], duration = duration, start = getTickCount( ), onChange = onChange, onEnd = onEnd}) return #anims end function destroyAnimation(a) if anims[a] then table.remove(anims, a) end end addEventHandler("onClientRender", root, function( ) local now = getTickCount( ) for k,v in ipairs(anims) do v.onChange(interpolateBetween(v.from, 0, 0, v.to, 0, 0, (now - v.start) / v.duration, v.easing)) if now >= v.start+v.duration then if type(v.onEnd) == "function" then v.onEnd( ) end table.remove(anims, k) end end end) function fadeOutSound(sound, fadeTime) animate(1.0, 0, 1, fadeTime, function(volumeValue) setSoundVolume(sound, volumeValue) if(sound and getSoundVolume(sound) == 0) then stopSound(sound) end end) end addCommandHandler("fadesound", function() fadeOutSound(test, 3000) -- Completely mute in 3 seconds end) Link to comment
βurak Posted February 1, 2022 Share Posted February 1, 2022 (edited) You're welcome. anytime Edited February 1, 2022 by Burak5312 Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now