Jump to content

CD Script


Zousug Corvinus
 Share

You are about to reply to a thread that has been inactive for 562 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hey,

Trying make a *CD* I can click to start playing a song.. i have it mostly finished but would like if it could put the time of the song I.e 00:00 - 04:35 and have it count up in to show where it is?

and how to stop it from playing once its finished lol it seems to repeat -.-

Below is my code so far.

integer clips;
integer toggle = TRUE;
float clip_length = 10;//in seconds
float last_clip_length = .05;//length of last clip in seconds
integer cycle;

init()
{
    toggle = TRUE;
    llSetTimerEvent(0);
    llSetSoundQueueing(FALSE);
    llStopSound();
    llTargetOmega(<0,0,0>,0,0);
    llSay(0,"Loading song please wait.");
    llSetSoundQueueing(TRUE);
    clips = llGetInventoryNumber(INVENTORY_SOUND);
    llPreloadSound(llGetInventoryName(INVENTORY_SOUND,0));
    llSleep(clip_length);
    llSay(0,"Touch to start.");
}

default
{
    state_entry()
    {
        init();
    }
    on_rez(integer param)
    {
        init();
    }

    touch_start(integer total_number)
    {
        if (llDetectedKey(0) == llGetOwner()) {
            if(toggle){
            toggle = FALSE;
            llSay(0,"Starting Player");
            llSetSoundQueueing(TRUE);
            
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,0),1.0);
            llPreloadSound(llGetInventoryName(INVENTORY_SOUND,1));
            cycle = 1;
            llSetTimerEvent(clip_length/2);
            }
            else {
            toggle = TRUE;
            llSetTimerEvent(0);
            llSay(0,"Player Stopped");
            llSetSoundQueueing(FALSE);
            llStopSound();
            }
        }
    }
    timer()
    {
            
            
            if(cycle < clips ){
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,cycle),1.0);
            cycle = cycle + 1;
                if(cycle < clips){
                llSetTimerEvent(clip_length);
                llPreloadSound(llGetInventoryName(INVENTORY_SOUND,cycle));
                }
                else {
                llSetTimerEvent(last_clip_length);
                llPreloadSound(llGetInventoryName(INVENTORY_SOUND,0));
                }
            }
            else {
            llSetTimerEvent(clip_length);
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,0),1.0);
            llPreloadSound(llGetInventoryName(INVENTORY_SOUND,1));
            cycle = 1;
            }    
            
    }
}

 

Edited by Zousug Corvinus
update
Link to comment
Share on other sites

2 hours ago, Zousug Corvinus said:

if it could put the time of the song I.e 00:00 - 04:35 and have it count up in to show where it is?

Using the hovertext property of the prim via llSetText and continually updating it each second would be one approach. The trouble is you'd need to rework your timer to support that. Essentially, you'd have to run the timer on a 1 second interval and then keep track of those intervals in a separate variable - similar to how you currently track clip cycles. Once that variable has gone up ten times, your logic would dip into the the code that handles cycling music clips (assuming each clip is 10 seconds long).

2 hours ago, Zousug Corvinus said:

how to stop it from playing once its finished lol it seems to repeat

Your code keeps repeating because there is no logic to tell it to stop after the last clip has played. In fact, the very last else clause of your code seems to set the thing up to restart once cycle becomes equal to or greater than clips. I suppose you would want to change that to instead set the timer to 0, which would break the loop.

  • Like 3
Link to comment
Share on other sites

lol do not ask me how.. but making changes i broke the script posted above...

I looked around and found one that is free-use and is very close to what I was trying to get but I still need a few things edited.. if someone can help me make the changes / point me in the right direction or even another one that dose it?

so when i click play with this one it says playing 1 of 30 *for example* i wanna change it to songs current time / total time instead, also it dosnt show the song name above this *it shows new end of the play for some reason* and last thing i need to do is make it so i can click it to stop it from playing as well atm it just restarts

i would really appreciate some guidance if possible.

 

// :CATEGORY:Music
// :NAME:Music Player
// :AUTHOR:Fred Beckhusen (Ferd Frederix)
// :CREATED:2013-09-06
// :EDITED:2013-09-18 15:38:58
// :ID:548
// :NUM:745
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// Sensor
// :CODE:

// 10-09-2012 by Fred Beckhusen (Ferd Frederix)

// May be triggered to run continually, start it by touching it or use the sensor script when someone gets nearby.

// This work is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License.
// http://creativecommons.org/licenses/by-nc/3.0/deed.en_US
// This script cannot be sold even as part of another object, it must always remain free and fully modifiable.

// Drop 10 second song clips in the inventory of the obect, and touch to play.
// A great free tool to make these files is the slice audio file splitter at http://www.nch.com.au/splitter/index.html
// Set the variable loop = TRUE to loop after reaching the end, set it to FALSE to play once.

// Scriptable Control:
// Send a link message string of 'play' and 'stop' for use with external control scripts.
// Or just touch the prim to play

integer loop = FALSE;                // set to TRUE to loop again and again
float set_text_alpha = 1;            // the text transparency fo alpha text. Set this to 0 to disable hovertext

// Stuff that you should not mess with:

integer debugflag = TRUE;           // chat debug info to owner if TRUE
integer waves_to_preload = 3;       // wave files to Preload ahead of the wav being played.
float preload_load_time = 0.5;      // seconds pause between each preloaded wave file attempt b4 play comnences
integer secret_channel = 54345;     // just a magic number
vector set_text_colour = <1,1,1>;   // colour of floating text label ( white)
float timer_interval = 9.8;         // time interval between requesting server to play the next 10 second wave
// times just below 10 seconds are suitable as we use sound queueing
integer total_wave_files;           // number of wave files
integer i_playcounter;              // used by timer() player
string preloading_wave_name;        // the name of the wave file being preloaded
string playing_wave_name;           // the name of the wave being played


DEBUG (string msg)
{
    if (debugflag) llOwnerSay(msg);
}


go(integer play) {

    if (play)
    {
        sound();

    } else {
            llSetTimerEvent(0.0);
        llStopSound();
        DEBUG("Stoped");
        llSetText(llGetObjectName() + "\n.", <0,1,0>, set_text_alpha);
    }
}



sound() {


    total_wave_files = llGetInventoryNumber(INVENTORY_SOUND);
    integer counter = 0;        //do full preload of sound
    llSetSoundQueueing(TRUE); // only works on llPlaySound not llTriggerSound, so we can queue these silently
    integer local_total_wave_files = total_wave_files -1 ;

    float length = total_wave_files * 10.0;
    for (counter = 0 ; counter < waves_to_preload ; counter++)  //preload X wave files b4 we play
    {
        //since wavs are numbered from 0 we minus 1
        preloading_wave_name = llGetInventoryName(INVENTORY_SOUND, counter);


        llSetText(llGetObjectName()
            + "Preload wav: " + (string)counter +"\n."
            +"\n.", <1,0,0>, set_text_alpha);
        //Attempt to preload first x wave files to local machines cache!
        llPreloadSound(preloading_wave_name);


        DEBUG("Preloading wav: " + (string)counter + " " + (string)llGetInventoryKey(preloading_wave_name));
        //start play sound timer in 'timer_interval' seconds when we are less than 'timer_interval' seconds from
        // finishing preloading.
        llSleep(preload_load_time);

    }
    llSetTimerEvent(0.1);   // start playing
    i_playcounter=0;
    counter=0;
}


default
{
    state_entry()
    {
        //set text above object to the name of the object
        llSetText(llGetObjectName() + "\n.", <0,1,0>, set_text_alpha);
    }

    touch_start(integer total_number)
    {
        go(TRUE);
    }

    timer()
    {
        llSetTimerEvent(timer_interval);
        if( i_playcounter > (total_wave_files -1) )
        {
            if (!loop)
            {
                llSetTimerEvent(0);
            }
            else
            {
                sound();
            }

        }  else {
                playing_wave_name = llGetInventoryName(INVENTORY_SOUND, i_playcounter);
            DEBUG("llPlaySound wav: " + (string)i_playcounter + " " + playing_wave_name );

            llPlaySound(playing_wave_name, 1.0);
            llSetText(  llGetObjectName() + "\n(playing " + (string)i_playcounter +" of "+ (string)(total_wave_files -1) +")\n.", <0,1,1>, set_text_alpha);
            if(i_playcounter + waves_to_preload <= (total_wave_files -1))
            {
                preloading_wave_name = llGetInventoryName(INVENTORY_SOUND, i_playcounter + waves_to_preload);
                llSetText("Playing " + (string)i_playcounter + " of " + (string)(total_wave_files -1) , set_text_colour, set_text_alpha);

                DEBUG("Preloading wav:" + (string)(i_playcounter + waves_to_preload) + "\n" +
                    (string) llGetInventoryKey(preloading_wave_name) +  "\n" +
                    "Preloading sequence: " + (string)(i_playcounter + waves_to_preload));


                llPreloadSound(llGetInventoryName(INVENTORY_SOUND, i_playcounter + waves_to_preload));
            }
        }
        i_playcounter++;     //increment for next wave file in sequence!
    }

    link_message(integer sender_number, integer number, string message, key id)
    {
        if (message == "play")
        {
            go(TRUE);
        }
        else if (message == "stop")
        {
            go(FALSE);
        }
    }

    on_rez(integer param)
    {
        llResetScript();
    }
}

 

Link to comment
Share on other sites

15 hours ago, Zousug Corvinus said:

lol do not ask me how.. but making changes i broke the script posted above...

What changes did you attempt? What error messages did you get? I would caution against jumping to a more complicated script as a template - because if you didn't understand what was going on in the simpler script, trying to understand the more complicated one will just make things unnecessarily harder.

Your original objective was to stop the song from auto-looping. Let's step through the code from your opening post and form a basic sequence of events. In the LSL editor, you can hover your mouse over each function to get a quick summary of what it does. See the LSL Wiki for more in depth information about a given function.

  1. At the start, the script runs the init() function, which sets some variables, stops any already playing sounds, and preloads the initial clip. Among the variables set is the clips variable. It gets populated with the number of sound files within the object's inventory.
  2. When the user touches the object, the touch_start event runs.
  3. Inside this event, the code fist checks if the person who touched it is the owner. If it is, it executes the remaining code.
  4. The code checks the toggle variable, which acts as an on-off switch. If the value of toggle is TRUE, it will flip the value to FALSE, announce it's starting the player, enable sound queuing, play the first clip in sequence, preload the next clip, set the cycle variable to 1, and finally start the timer countdown to execute the timer event in 5 seconds (half of the defined clip length of 10).
  5. On the other hand, if the toggle variable was FALSE when the object was clicked, the code would instead set toggle to true (see how it's flipping the switch each time?), stop the timer countdown (by setting it to zero), announce the player has stopped, disable sound queuing, and stop any currently playing sounds.
  6. Assuming that toggle was TRUE in step 4, at this point the player is running and the first clip is playing.
  7. 5 seconds after starting, the timer event is triggered.
  8. The code inside the timer event first checks if the cycle variable is less than the clips variable. Remember that clips represents the total number of sound files in the object and cycle represents which clip is currently playing. Since we just started, cycle is currently set to 1 (it was set in step 4). Let's assume there are 3 sound files in this example, so at present, 1 is less than 3 so the if-statement evaluates to true and executes the underlying code.
  9. This means the script will play the next sound in sequence, using the cycle variable as the index. (inventory items are indexed starting at zero, so with cycle currently being equal to 1, that means it's playing the second clip).
  10. Then, the code increments cycle by 1.
  11. It then checks again if the now updated value of cycle is still less than clips. If it is, the timer countdown is set to be the clip_length (10 seconds) and it preloads the next clip in sequence. This is the crux of the loop. The timer event will continue to trigger every 10 seconds and each time it will play the queued up sound, increment the cycle variable, and preload the next sound as long as the value of cycle remains less than the value of clips.
  12. Now if the value of cycle is equal to or grater than clips, that means we've played all of the clips and are nearing the end of the song. So the test in step 11 would instead run the code in the else clause: which is to say it would instead alter the timer to trigger in last_clip_length seconds and then preload the very first clip in the sequence (remember they're zero-indexed).
  13. When the timer event triggers again and value of cycle is not less than clips, then the initial test in step 8 will evaluate to FALSE and the else clause will execute instead. In this case, the timer countdown is set for the standard clip length (10 seconds), the first clip is played, and the 2nd clip is preloaded (remember these are indexed stating at zero). Finally, it also sets cycle to 1 which completes the loop.

 

This is a brief walk-through of the code. So if you want to stop this from looping forever, you would want to at minimum, set the timer event to zero seconds in step 13. I'd also set the toggle variable to equal FALSE here as well so that you don't have to click it twice to restart.

Edited by Fenix Eldritch
  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 562 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...