There is a chance that the memory will break if the playlist is made too long. V3 will include a measure against that but I have to sleep occasionally.
// V2 //
// This list is all you need to edit. List the names of the songs (each collection of sound files that makes one song)
// followed by the length of those sound clips (each song should contain clips of equal length)
// The list should be structured like so -
// list songs = ["First Song", 9.0, "Second Song", 9.65, "Third Song", 9.45];
// The names of the songs must be identical to some part of the sound files used for that song like so -
//// In the prim inventory (along with this script) -
////// Box_Of_Rain_wav_1
////// Box_Of_Rain_wav_2
////// Box_Of_Rain_wav_3
////// Servant 1
////// Servant 2
////// Servant 3
//// In the script -
////// list songs = ["Box_Of_Rain", 9.2, "Servant", 9.8];
// The script will play the clips in alpha/numerical order so name them wisely.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////ONLY EDIT BELOW HERE///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
list songs = ["Box_Of_Rain", 9.2, "Servant", 9.8]; // YUP! EDIT THIS BIT ;-)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////ONLY EDIT ABOVE HERE///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
integer volume = 10;
integer lis_count;
integer playing;
integer busy;
integer part;
integer lis;
integer sl;
float delay;
list cancel = ["CANCEL"];
list playlist;
list waiting;
list song;
string vol_str = "Volume";
string song_str = "Songs";
string song_name;
list StrideOfList(list src, integer stride, integer start, integer end)
{
list l = [];
integer ll = llGetListLength(src);
if(start <0)start += ll;
if(end < 0)end += ll;
if(end < start) return llList2List(src, start, start);
while(start <= end)
{
l += llList2List(src, start, start);
start += stride;
}
return l;
}
list Volumes(integer vol)
{
integer v = 0;
list l = [];
do
{
if(v != vol)
l += [((string)v)];
}
while((++v) <= 10);
return l;
}
PageOne(key k, integer c)
{
llDialog(k, "\nAdjust the volume or select a song to play?", [vol_str, song_str] + cancel, c);
}
PlaySong(string n)
{
song = [];
integer c = -1;
string name = "";
do
{
if(llSubStringIndex((name = llGetInventoryName(INVENTORY_SOUND, (++c))), n) != -1)
song += [name];
}
while(name);
delay = llList2Float(songs, (llListFindList(songs, [n]) + 1));
if((sl = llGetListLength(song)))
{
llPreloadSound(llList2String(song, (part = 0)));
if(sl > 1)
llPreloadSound(llList2String(song, 1));
playing = FALSE;
llSetTimerEvent(0.01);
}
}
integer Chan()
{
return llRound((llFrand(-5000000.0) + -500000.0));
}
float ScaleVol(integer v)
{
return (v * 0.1);
}
Listen(integer c, key a)
{
lis = llListen(c, "", a, "");
}
RemoveListen(integer b)
{
llListenRemove(lis);
lis_count = 0;
if(b)
busy = FALSE;
lis = 0;
}
SetListenTimer(integer p)
{
if(p)
while(((++lis_count) * llRound(delay)) ><30);
else
{
lis_count = 1;
llSetTimerEvent(30.0);
}
}
integer CheckWaitingRoom(integer c)
{
if(waiting)
{
key a = llList2Key(waiting, 0);
if(!c)
{
RemoveListen(0);
Listen((c = Chan()), a);
SetListenTimer(playing);
}
PageOne(a, c);
waiting = llDeleteSubList(waiting, 0, 0);
return 1;
}
return 0;
}
default
{
on_rez(integer param)
{
llStopSound();
llResetScript();
}
changed(integer change)
{
if(change & CHANGED_INVENTORY)
llResetScript();
}
touch_start(integer nd)
{
while(nd)
{
key agent = llDetectedKey(--nd);
if(!busy)
{
busy = TRUE;
integer channel = Chan();
SetListenTimer(playing);
Listen(channel, agent);
PageOne(agent, channel);
}
else
{
list a = [agent];
if(llListFindList(waiting, a) == -1)
waiting += a;
}
}
}
listen(integer chan, string name, key id, string msg)
{
if(msg != llList2String(cancel, 0))
{
SetListenTimer(playing);
if(msg == vol_str)
{
llDialog(id, "\nChange the volume?\nThe current volume is set at \"" + ((string)volume) + "\"", cancel + Volumes(volume), chan);
return;
}
if(msg == song_str)
{
string current = "";
if(playlist)
{
current = "\n\nThe songs currently queued are\n\"" + llList2String(playlist, 0) + "\" (currently playing)";
if(llGetListLength(playlist) > 1)
current += "\n\"" + llDumpList2String(llList2List(playlist, 1, -1), "\"\n\"") + "\"";
}
llDialog(id, llGetSubString(("\nSelect a song to play?" + current), 0, 500), cancel + StrideOfList(songs, 2, 0, -1), chan);
return;
}
if(llListFindList(Volumes(volume), [msg]) != -1)
{
llAdjustSoundVolume(ScaleVol((volume = ((integer)msg))));
PageOne(id, chan);
return;
}
if(llGetListLength((playlist += [msg])) == 1)
PlaySong((song_name = msg));
}
if(CheckWaitingRoom(chan))
return;
RemoveListen(1);
}
timer()
{
if(playlist)
{
if(!playing)
{
llSetTimerEvent(delay);
playing = TRUE;
}
llPlaySound(llList2String(song, part), ScaleVol(volume));
if((++part) == sl)
{
if(llGetListLength(playlist) > 1)
{
song_name = llList2String((playlist = llDeleteSubList(playlist, 0, 0)), 0);
llSleep(delay);
PlaySong(song_name);
}
else
{
llSetTimerEvent(0.0);
song_name = "";
playing = FALSE;
playlist = [];
}
}
else if(part == (sl - 1))
llPreloadSound(llList2String(song, 0));
else
llPreloadSound(llList2String(song, (part + 1)));
}
if(lis && (!(--lis_count)))
{
if(!(CheckWaitingRoom(0)))
RemoveListen(1);
}
}
}>