rekkless 240 Posted November 23, 2015 Ok so I've searched everywhere for a proper example on how to efficiently make music loop.I have a track that is actually ambient sounds that goes for 6:15. at the end of the 6 minutes and 15 seconds I want to track to replay and keep replaying until the end of the mission.Now I would specifically like it to be classed as a music track so players can adjust the volume using their music volume controls instead of sound effect controls. That was plays can have the option of turning the ambient sounds all the way off, just down a little or have them full blast.I have the music set up already Music 1 in a music folder and I have the music set up already in the description: class CfgMusic { tracks[]={}; class music1 {name = "music1"; sound[] = {"\music\music1.ogg", db+3, 1.0}; }; }; and I know how to get it to play using a trigger. The problem is getting it to loop once the track has finished. Can anyone point me in the right direction please. Share this post Link to post Share on other sites
Rydygier 1317 Posted November 23, 2015 A simple loop like this: my_music_handle = [] spawn { while {true} do { playMusic "music1"; sleep 675 } }; may be pasted in the any place in the code, you want, or eg in the trigger's exec/act window to start, when required. Pause is in seconds, may be longer, if interval is required. my_music_handle additionally may be used to terminate the loop any time from any place: terminate my_music_handle; Another way involves this EH. Share this post Link to post Share on other sites
rekkless 240 Posted November 23, 2015 A simple loop like this: my_music_handle = [] spawn { while {true} do { playMusic "music1"; sleep 675 } }; may be pasted in the any place in the code, you want, or eg in the trigger's exec/act window to start, when required. Pause is in seconds, may be longer, if interval is required. Where do I post this? In the trigger? I would like the ambient music to start 3 minutes after spawn and continue to play until the end of the mission. The current track is 6 minutes 15 seconds. Share this post Link to post Share on other sites
Rydygier 1317 Posted November 23, 2015 may be pasted in the any place in the code, you want, or eg in the trigger's exec/act window to start, when required. So, if you paste in into the trigger, all to do is set properly condition of this trigger to be activated 3 minutes after mission start: time > 180; Note, if this is for multiplayer mission, some things may differ - MP can make simple things difficult, so it's important to point, if this is SP or MP. My assumption always is SP. Not sure about MP - ask someone else in such case. Share this post Link to post Share on other sites
rekkless 240 Posted November 23, 2015 So, if you paste in into the trigger, all to do is set properly condition of this trigger to be activated 3 minutes after mission start: time > 180; Note, if this is for multiplayer mission, some things may differ - MP can make simple things difficult, so it's important to point, if this is SP or MP. My assumption always is SP. Not sure about MP - ask someone else in such case. Yeah sorry I missed that part. So far so good, thanks mate. Can you tell me what the Sleep 675 means? If I should choose to change the track to something else other than renaming the new track to music1 is there anything else I need to do? Share this post Link to post Share on other sites
killzone_kid 1331 Posted November 23, 2015 Sleeping for 675 seconds does not guarantee that after 675 seconds the scope will end, it could be 765 seconds for example or 699 or.. this is very very very unreliable and I would advise not to do this. Instead there is a dedicated Music EH that can execute given code EXACTLY when music stops https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#addMusicEventHandler 1 Share this post Link to post Share on other sites
Rydygier 1317 Posted November 23, 2015 Can you tell me what the Sleep 675 means? It means: wait 675 seconds before go further. It's inside infinite loop, so the logic is: "Ad infinitum" do following: 1. Play music track; 2. Wait 675 seconds. So the code will repeat subsequently these two steps all the time, till end of mission or terminating whole code. Share this post Link to post Share on other sites
Rydygier 1317 Posted November 23, 2015 Sleeping for 675 seconds does not guarantee that after 675 seconds the scope will end, it could be 765 seconds for example or 699 or.. this is very very very unreliable So far worked just fine for me. May be enough for simplicity - why to complicate. From the other hand, music EH sometimes failed for me in my tests, so not sure, what's more reliable. Let him try simplier way first. Share this post Link to post Share on other sites
Rydygier 1317 Posted November 23, 2015 If I should choose to change the track to something else other than renaming the new track to music1 is there anything else I need to do? With "sleep method" obviously the lenght of the sleep should be adjusted to fit the song length. For music EH way - not required. In this way code awaits specifically for the end of playing music instead of awaiting given amount of time. Exemplary approach would be then: ehID = addMusicEventHandler ["MusicStop", {music_isPlaying = false}]; my_music_handle = [] spawn { while {true} do { music_isPlaying = true; playMusic "music1"; waitUntil { sleep 1; not music_isPlaying } } }; Share this post Link to post Share on other sites
1212PDMCDMPPM 200 Posted November 23, 2015 IIRC, play your music as an environment sound through a trigger. Use the extra screen in the trigger screen - Effects button then choose "environment" (3rd list in this arma 2 screen: https://community.bistudio.com/wikidata/images/0/04/Arma2_editor_effects.jpg). The file will be looped until the end of the mission. Share this post Link to post Share on other sites
R3vo 2654 Posted November 23, 2015 With "sleep method" obviously the lenght of the sleep should be adjusted to fit the song length. For music EH way - not required. In this way code awaits specifically for the end of playing music instead of awaiting given amount of time. Exemplary approach would be then: ehID = addMusicEventHandler ["MusicStop", {music_isPlaying = false}]; my_music_handle = [] spawn { while {true} do { music_isPlaying = true; playMusic "music1"; waitUntil { sleep 1; not music_isPlaying } } }; Why so complicated? ehID = addMusicEventHandler ["MusicStop", {playMusic "music1";}]; Share this post Link to post Share on other sites
killzone_kid 1331 Posted November 23, 2015 Works for me just fine and is much simpler than using unreliable sleep: addMusicEventHandler ["MusicStop", {playMusic ["RadioAmbient3", 8]}]; playMusic ["RadioAmbient3", 8]; Share this post Link to post Share on other sites
Rydygier 1317 Posted November 23, 2015 Why so complicated? In this particular case - redundant indeed. Examples by me was pasted from something more complex and adapted for required use. The file will be looped until the end of the mission. If so, that would be a simpliest way for someone, that don't want to hassle with any scripting. Share this post Link to post Share on other sites
1212PDMCDMPPM 200 Posted November 23, 2015 Things I forgot about envSound: Those are looped until the end of the mission BUT they are not music, you need to put them in class CfgEnvSounds. I don't think you can manually adjust the sound through the music slider (or script command). rekkless, do you need your environment music to be less loud when indoor ? If yes, I have a small script, courtesy of JSRS, that does the detection and lower the music level. Share this post Link to post Share on other sites
killzone_kid 1331 Posted November 23, 2015 Things I forgot about envSound: Those are looped until the end of the mission BUT they are not music, you need to put them in class CfgEnvSounds. I don't think you can manually adjust the sound through the music slider (or script command). rekkless, do you need your environment music to be less loud when indoor ? If yes, I have a small script, courtesy of JSRS, that does the detection and lower the music level. There is always https://community.bistudio.com/wiki/setMusicEffect Share this post Link to post Share on other sites
barbolani 198 Posted November 23, 2015 A copy paste of Antistasi's situational music script, may be useful: _normaldia = ["LeadTrack01_F", "LeadTrack01a_F", "LeadTrack01b_F", "LeadTrack02_F", "AmbientTrack03_F", "BackgroundTrack01_F", "BackgroundTrack01a_F", "Track02_SolarPower"]; _normalnoche = ["Track08_Night_ambient", "Track09_Night_percussions","Track11_StageB_stealth"]; _combat = ["LeadTrack03_F", "LeadTrack04_F", "LeadTrack04a_F", "LeadTrack05_F", "BackgroundTrack03_F", "Track01_Proteus", "Track07_ActionDark","Track10_StageB_action"]; _stealth = ["LeadTrack06_F", "AmbientTrack01_F", "AmbientTrack01a_F", "AmbientTrack01b_F", "AmbientTrack04a_F", "AmbientTrack04_F", "Track04_Underwater1","Track05_Underwater2"]; _stance = behaviour player; _newstance = _stance; cambioMUS = true; _cancion = "LeadTrack01_F"; while {musicON} do { sleep 3; _newstance = behaviour player; //hint format ["El jugador está en esta stance: %1", _newstance]; sleep 3; if ((_newstance != _stance) or (cambioMUS)) then { removeAllMusicEventHandlers "MusicStop"; _stance = _newstance; if (_newstance == "COMBAT") then { _cancion = _combat call BIS_Fnc_selectRandom; cambioMUS = true; }; if (_newstance == "STEALTH") then { _cancion = _stealth call BIS_Fnc_selectRandom; cambioMUS = true; }; if ((_newstance == "AWARE") or (_newstance == "SAFE")) then { if ((daytime > 18) or (daytime < 6)) then { _cancion = _normalnoche call BIS_Fnc_selectRandom; cambioMUS = true; }; if ((daytime > 5) or (daytime < 19)) then { _cancion = _normaldia call BIS_Fnc_selectRandom; cambioMUS = true; }; }; 5 fadeMusic 0; }; if (cambioMUS) then { _EH = addMusicEventHandler ["MusicStop", {cambioMUS = true}]; cambioMUS = false; sleep 5; 1 fadeMusic 0.5; playmusic _cancion; }; if (!musicON) then { 1 fadeMusic 0.5; sleep 0; playMusic ""; }; }; musicON is the variable that turns on or off the music, use radio trigger, dialog or whatever. On act: musicON = true and execute the script, on deact: musicON = false; Don't know if it's good or not, but worked for ages. 1 Share this post Link to post Share on other sites
rekkless 240 Posted November 23, 2015 Oh boy, you guys have posted a lot of information and I'm not sure I'm any more clear on what to do than before.The "track" (it isn't music but ambient sound) i want to be controlled by the players music volume not their sound effects volume. I want the track to start 3 minutes after the mission has started and repeat until the end of the mission. Terminating the track is not necessary I just need it to efficiently and reliably keep playing after all like I said it is ambient sounds. the track goes for 6 minutes and 15 seconds. What exactly do I have to put in the trigger to make "Music1" (the ambient sound) play and repeat. and if I don't post the code in the trigger where do I post it? If I post this in the activ part of the trigger with a delay of 180 seconds will the track "music1" play and repeat? ehID = addMusicEventHandler ["MusicStop", {playMusic "music1";}]; Share this post Link to post Share on other sites
Rydygier 1317 Posted November 24, 2015 If I post this in the activ part of the trigger with a delay of 180 seconds will the track "music1" play and repeat? To be exact: like killzone_kid pasted: ehID = addMusicEventHandler ["MusicStop", {playMusic "music1";}];playMusic "music1"; Because "MusicStop" awaits, till... music stops :) before will run contained code, so you have to run the music once after adding this music EH, or "musicStop" will have no opportunity to be activated due to lack of music playing. That one indeed should be best for your use. and if I don't post the code in the trigger where do I post it? Init.sqf is usual way. Just 1. go to your mission foler saved by editor, 2. create a new text file there, 3. paste directly such code into this file: sleep 180; ehID = addMusicEventHandler ["MusicStop", {playMusic "music1";}];playMusic "music1"; or, if you too don't trust "sleep", alternatively: waitUntil { sleep 1; (time > 180) }; ehID = addMusicEventHandler ["MusicStop", {playMusic "music1";}];playMusic "music1"; 4. save, then rename the file to init.sqf. 3 and 4 order can be swapped, sqf files may be edited via notepad. Share this post Link to post Share on other sites
BB-Winter 0 Posted September 17, 2016 Some great support from this thread thanks guys Share this post Link to post Share on other sites
theend3r 83 Posted September 18, 2016 I've written a simple script for looping and randomizing music. It works really well and you can just execute it again with different arguments so you can use it in triggers to change between calm/suspicious/battle music... etc. It's old, so the writing is messy but it works. private "_track"; private "_previous"; private "_random"; private "_tracknumber"; _fade = 1.5; // set the fade duration _tracks = _this select 0; // tracks array _repeat = _this select 1; // Play indefinitely? true/false _onload = _this select 2; // Play after loading a save? true/false if (count _this > 3) then {_random = _this select 3}; // 0 = seqence, 1 = random track each time, 2 = random track repeatedly if (count _this > 4) then {_previous = _this select 4}; // define this to start from the next track / other random track, otherwise do not define it /* examples for in-game use: _nul = [["track1", "track2", "track3"], false, true, 1, "track2"] execVM "music.sqf" - randomly play a track, also play it after a save is loaded _nul = [["track1", "track2", "track3"], true, true] execVM "music.sqf" - play all tracks sequentially until overwritten or aborted with playmusic "" */ if (typeName _tracks != "ARRAY") then {_tracks = [_tracks]}; if (isNil "_random") then {_random = 0}; if (isNil "_previous") then {if (_random == 0) then {_previous = _tracks select (count _tracks - 1)} else {_previous = selectRandom _tracks};}; switch (_random) do { case 0: { _tracknumber = (_tracks find _previous) + 1; if (_tracknumber > count _tracks - 1) then {_tracknumber = 0}; _track = _tracks select _tracknumber; }; case 1: {if (count _tracks > 1) then {_track = selectRandom (_tracks - [_previous])} else {_track = _tracks select 0};}; case 2: {_track = _previous;}; default {hint "Music Error"}; }; //hint format ["Tracklist: %1\nCurrent track: %2\nPrevious track: %3\nList progress: %4/%5\nRandom: %6", _tracks, _track, _previous, (_tracks find _track) + 1, count _tracks, _random]; // debug removeAllMusicEventHandlers "MusicStop"; removeAllMissionEventHandlers "Loaded"; if (_repeat) then {call compile format ["addMusicEventHandler ['MusicStop',{[%1, %2, %3, %4, '%5'] execVM 'music.sqf';}]", _tracks, _repeat, _onload, _random, _track];}; if (_onload) then {call compile format ["addMissionEventHandler ['Loaded',{[%1, %2, %3, %4, '%5'] execVM 'music.sqf';}]", _tracks, _repeat, _onload, _random, _track];}; [_fade, _track] spawn {(_this select 0) fademusic 0; sleep ((_this select 0) + 0.2); playmusic format ["%1",(_this select 1)]; (_this select 0) fademusic 1;}; Share this post Link to post Share on other sites
badpr1m3r 2 Posted October 11, 2017 Awesome thread eventhandler works like a charm. I have it set up where upon entering and leaving a house the music is played on loop. Once I leave the house I fade the music to 0. However once the other music at the objectives is finished playing it reverts back to the music loop I have reserved for only inside the house.... Any ideas? Share this post Link to post Share on other sites
Undeceived 392 Posted October 11, 2017 Just to complete this good collection, there is also the script Cly_Jukebox by @celery. Awesome script - playlist, looping, random order and it does even resume the track when loading a saved game. (sorry @badpr1m3r, I didn't really reply to your post...) Share this post Link to post Share on other sites
soolie 189 Posted October 11, 2017 I know you already figured it out with the music eh but just wanted to throw this out there. iirc sleep is unreliable when using large numbers. I believe this is the best way to call a long sleep. for "_i" from 1 to 180 do { sleep 1; }; 1 Share this post Link to post Share on other sites
badpr1m3r 2 Posted October 12, 2017 removeMusicEventHandler ["MusicStop", ehID]; Is to stop the loop. Share this post Link to post Share on other sites
jonilahtinen 15 Posted August 20, 2020 On 11/23/2015 at 4:23 PM, killzone_kid said: Works for me just fine and is much simpler than using unreliable sleep: addMusicEventHandler ["MusicStop", {playMusic ["RadioAmbient3", 8]}]; playMusic ["RadioAmbient3", 8]; "Error, invalid number in expression" Share this post Link to post Share on other sites