Jump to content

llPlaySound plays the sound twice (or more)


Rick Nightingale
 Share

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

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

Recommended Posts

Has anyone seen an issue where llPlaySound with llSetSoundQueueing plays a sound more than once, or a subsequent call to llPlaySound with a different sound plays the previous sound again? I'm certain my script isn't calling it more than once...

My script plays assorted sounds on the click of a HUD button. The sounds' names and durations are on a NC. Some of the sounds are multiple files split into 10 second lots, some are just a single file.

In order to allow duplicate sounds to be played in succession (which llSetSoundQueueing does not allow) my script plays a "silence" file after every sound set. The HUD also has a Stop button which cancels any pending sound files in my queue and plays the "silence". If the script has a queue, each 'next' sound is preloaded with llPreloadSound as it is queued for playing, while the previous one is still playing.

It all works perfectly and has for years... except in one region I tend to visit a lot: Fallen Gods.

There, it will more often than not (but not always) play a sound twice, or even loop it (possibly indefintely, certainly 3+ times) until I press the Stop button. I'm only playing a single sound file, not one with multiple files chained together, so there is no actual queuing or preloading involved in this case.

I have debugged the script with chat messages for every step, and it does nothing unexpected that should trigger the sound again. The llPlaySound function is only called as expected. The main script is in an attachment and listens to the HUD.

This is the script in the attachment. Not all is shown (to keep it brief) but the missing code plays no part in the issue. The HUD script simply sends commands and doesn't play anything itself.

key Owner;
integer vChannel=[redacted my secret channel]
list Length;        // Play lengths
list Sound;            // Sound names
integer Playing;    // Index of playing sound. -1=nothing playing
integer Queue;        // Queue depth
integer Volume=7;    // Volume (1..10)

Playit(string thesound, float thevolume) {
	llPlaySound(thesound,thevolume);
	llOwnerSay(thesound);
}

default{
	state_entry(){
		Owner=llGetOwner();
		llSetSoundQueueing(1);
		state Running;
	}
}

state Running {
	state_entry(){
		llListen(vChannel,"","","");
		Length=Sound=[]; Playing=-1;
	}

	listen(integer channel, string name, key id, string m) {
		if (llGetOwnerKey(id)!=Owner) return;
		llOwnerSay("Heard: "+m);
		list task=llCSV2List(m); integer tasklen=llGetListLength(task)/2;
		if (tasklen) {    // Should be a playlist
			llOwnerSay("Heard a playlist");
			if (Queue) {    // Already a queue, check for duplicate entry (cannot queue successive duplicates)
				llOwnerSay("There's a Queue");
				if (llList2String(Sound,-1)==llList2String(task,0)) {    // We have a successive duplicate
					Sound+="silence"; Length+="0.1";
				}
			}
			Sound+=llList2List(task,0,tasklen-1);
			Length+=llList2List(task,tasklen,-1);
			if (Playing==-1) {    // Not currently playing, start it up
				llOwnerSay("Wasn't playing, is now");
				Playit(llList2String(Sound,Playing=0),0.1*Volume);
				llResetTime();
				llSetTimerEvent(0.02);    // Trigger the next sound queueing
			}
			else if (Playing==Queue) {    // We have already started the previous last sound, need to rejig the timing
				llOwnerSay("Already playing, rejig");
				--Playing;
				llSetTimerEvent(0.02);
			}
			Queue=llGetListLength(Sound);
		}
		else {
			if (m=="stop") {
				Playit("silence",0.0);
				llSetTimerEvent(0.0);
				Length=Sound=[]; Playing=-1; Queue=0;
			}
			else if ((integer)m) {
				Volume=(integer)m;
			}
		}
	}

	timer(){
		if (++Playing<Queue){    // We have more to queue
			llPreloadSound(llList2String(Sound,Playing));        // Preload the next sound...
			Playit(llList2String(Sound,Playing),0.1*Volume);        // ... and queue it
			float delay=llList2Float(Length,Playing-1)-1.04;
			if (delay<=0) delay=0.02;
			llSetTimerEvent(delay);
			llOwnerSay("TimerA: "+"P="+(string)Playing+" Q="+(string)Queue+" D="+(string)delay);
		}
		else if (Playing==Queue) {    // Last sound should now be playing, give it time to finish
			float delay=llList2Float(Length,Playing-1)-1.04;
			if (delay<=0) delay=0.02;
			llSetTimerEvent(delay);
			llOwnerSay("TimerB: "+"P="+(string)Playing+" Q="+(string)Queue+" D="+(string)delay);
		}
		else {
			llSetTimerEvent(0.0);
			Playit("silence",0.1*Volume);
			Length=Sound=[]; Playing=-1; Queue=0;
			llRegionSayTo(Owner,vChannel,"stop");
			llOwnerSay("TimerC: "+"P="+(string)Playing+" Q="+(string)Queue);
		}
	}
}

 

This is the debug chat:

Heard: Darkness Laugh =7.75,7.75
Heard a playlist
Wasn't playing, is now
Playing: Darkness Laugh =7.75
TimerB: P=1 Q=1 D=6.710000
Playing: silence
TimerC: P=-1 Q=0

As you can see, the debug shows only two calls to llPlaySound. Everything is as expected, and yet the sound "Darkness Laugh =7.75" played three times on that run!

Finally, I've realised as I typed this that when I press stop, the sound stops immediately. As I understood it, the "silence" should be queued up but the currently playing sound should still finish because of the llSetSoundQueueing(1) in the default state_entry.

 

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1664 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...