Thursday, February 11, 2016

OpenSim VR up to one minute sounds

update: added to the OpenSim Kokua viewer.

update: now added to

eta: added to the next release of Firestorm eta: I was just told it would be added to the next Kokua viewer release 21 May 2016.

update: This has been added to the Alchemy viewer as seen here. And here is the firestorm viewer jira report. I was also told that SL may raise the limit which would result in all TPVs (third party viewers) adding the code eventually. Works great with this alchemy version.

All mentions of the use of meerkat for this are now superseded by the 4.0.0 Alchemy link above 18 April 2016.

Recently I was involved in a g+ conversation where a friend of mine, Shelenn Ayres, mentioned a way to upload sound files longer than the default and typical 10 seconds.

OpenSim is an aspect of Virtual Reality, a platform as can be read about here.

There are viewers that have been created in order to log into them.

Firestorm is one of them and I use it normally. Meerkat is another one that is no longer supported but can be used for this. Choose your own flavor but I used "Meerkat_0-2-2-211_Setup.exe" for my win10 PC.

I got some long files from freesound (that is one file I used to test it initially). It is a 56 second file.

I use audacity to manipulate sound files and you can change the project rate (bottom left side of the program) to "44100" (many come in at other numbers so please watch is a requirement of the viewers).

I then exported it as a type ".wav microsoft signed 16 bit pcm" (you can add metadata during this when the screen is offered).

WavePad Audio File Splitter is really nice also.

Then I started Meerkat in my own simonastick (a local simulator instance), it worked there, so then I tried it in Kitely (another opensim "grid"). I uploaded it and it played. I then put it in a prim with a touch to start sound script and it played there as well.



    touch_start(integer total_number)


        //Play a Sound file Once that is in Object Inventory

        llPlaySound(llGetInventoryName(INVENTORY_SOUND,0), 1);



I then proceeded to test a longer file of 2 minutes 27 seconds.

I was able to upload it using Meerkat (as I could also do with a 4 minute song) but it would only play 1 minute if it. Firestorm would not play those at all.

I cropped the long file down to 2 minutes and then to 1 minute. Further testing to confirm the longest sound file I could use.

One minute appears to be the limit but there could be other issues using other viewer software programs or in different versions of opensimulator (ymmv).

That is for others to test if they wish to, and hopefully get back to me with their findings.

I can imagine quite a few additional uses for this rather than the otherwise limiting 10 seconds.

As it seems obvious (at least to this rather non techy woman) this is a viewer limitation, I wonder why and I wonder if it relates to some SecondLife forced limitations other viewers had to implement in order to comply with their rules.

If so, then it might be possible to get longer sound file implementations for OpenSim only...I leave that to others to pass along if they wish to.

This blog will change depending upon any further information others may let me know of, or in the comments.

Have fun and let me know how it goes for you also, if you wish-)

updated to add: Freesound is having some issues lately. I also wanted to add that you can pull songs (and any sounds) out of youtube to test this.

Just further manipulate the files in Audacity.

Always keep an eye on licensing.

updated: another person brought up stitching sound segments together.

Here is a video about using Audacity to break up a file into segments.

Here is an online service which stitches segments.

eta: 11 March 2016: I found another script that seems to work better than the other one for this. It preloads the sounds:
// Script Name: Music_Box.lsl
// CATEGORY: Music
// AUTHOR: Ferd Frederix
// COMPATIBILITY: Second Life, Opensim
// Sensor Script - Put this in a prim along with the Music script and as many 10 second sound clips as you want.   This will detect any avatar coming nearby and trigger the music from the beginning.   You can leave this script out and just use the music player. Start the music by touching the prim
//////////////////////// ORIGINAL AUTHORS CODE BEGINS ////////////////////////////////////////////
// Music player script.   Can play up to 254 10 second clips in sequence.  Trigger it with a link message, the above sensor script, or touch the prim
// 10-09-2012 by 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.
// 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
// 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
//modified for 60 second or less sounds when Meerkat viewer uploads them Isolde Caron  3.11.16
integer loop = TRUE;                // 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 = FALSE;           // chat debug info to owner if TRUE
integer waves_to_preload = 2;       // wave files to Preload ahead of the wav being played.
float preload_load_time = 0.0;      // seconds pause between each preloaded wave file attempt b4 play commences
integer secret_channel = 54345;     // just a magic number
vector set_text_colour = <1,1,1>;   // colour of floating text label ( white)
float timer_interval = 60.0;         // time interval between requesting server to play the next 60 second wave
// times just below 60 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)
    } else {
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 * 60.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);
        //Attempt to preload first x wave files to local machines cache!
    llSetTimerEvent(0.1);   // start playing
        //set text above object to the name of the object
        //llSetText(llGetObjectName() + "\n.", <1,0,0>, set_text_alpha);
    touch_start(integer total_number)

        if( i_playcounter > (total_wave_files -1) )
            if (!loop)

        }  else {
                playing_wave_name = llGetInventoryName(INVENTORY_SOUND, i_playcounter);
                      llTriggerSound(playing_wave_name, 1.0);
            if(i_playcounter + waves_to_preload <= (total_wave_files -1))
                preloading_wave_name = llGetInventoryName(INVENTORY_SOUND, 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")
        else if (message == "stop")

    on_rez(integer param)