Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Soundplayer script

Slayd Lemieux
Registered User
Join date: 9 Jul 2005
Posts: 29
08-31-2005 22:52
Strange how when I post there's almost always another related question posted, heheh.
Anywho, I've been working on a script for a few days and have come to a point where I need a hand! Don't know how to post the script into a window in the thread, if someone will give me a hint I'll do that as well. Here's the jist of it.

It's a voice activated, menu based, sound player.
I have two notecards set up for it to read so the user can add/remove sounds.
One contains the text they want displayed on the buttons, and the other is the actual names of the sound files to be played. I could make these into one notecard, but it'd create a whole lot more work earlier on in the script.
I have lists made for each notecard.

So here's where I'm stuck.

When the person clicks on the sound the want played, I'm not sure how to make that correspond to a certain line in the soundfile notecard.

Example... The user clicks the 3rd button (we'll say it's "Hi!";), I'd want the 3rd sound in the notecard to be played(which may be "hi.wav";).


I'm assuming I'll need it to check the message recieved ("Hi!";) against the buttons list, and find which entry number it is in the list.. should be #3. Store that integer, and then have the script check line #3 in the sounds list... which should be "hi.wav".

I'm sure I can get it to play the sound once the sound's name has been retrieved. Just need some help getting the above figured out.

Any help at all will be greatly appreciated! If you need some more clarification on the script, lemme know. And I'll be more then happy to post the script.

Thanks!
a lost user
Join date: ?
Posts: ?
09-01-2005 01:10
Provided the sounds list and the names list is ordered correctly, it's fairly straight forward. For example if the sounds note card has:
hi.wav
goodbye.wav
woohoo.wav

And the names notecard had:
Hello
Good bye
Woooo hoooo!!

So, each line corresponds with the SAME LINE in the other notecard...

CODE

// Lists for sounds and things to say
list sounds;
list names;

// Notecard stuff
string Card1 = "Sounds";
key gSounds;
string Card2 = "Names";
key gNames;
integer gLine;
integer serving_data;

// Listening and dialog stuff
integer listening;
integer dchannel = 98347;

start_listen(key id)
{
if(listening) llListenRemove(listening);
listening = llListen(dchannel,"",id,"");
}

default
{
state_entry()
{
serving_data = TRUE;
gSounds = llGetNotecardLIne(Card1,gLine);
gLine++;
}

dataserver(key query, string data)
{
if(gSounds == query)
{
if(data != EOF)
{
if(data != "") // discard blank lines
{
sounds += data;
if(llGetInventoryKey(data) == NULL_KEY)
llOwnerSay("Warning: " + data + " not found in inventory.");
}
gSounds = llGetNotecardLine(Card1,gLine);
gLine++;
}
else
{
gLine = 0;
gNames = llGetNotecardLine(Card2,gLine);
gLine++;
}
}

if(gNames == query)
{
if(data != EOF)
{
if(data != "") // discard blank lines
{
names+= data;
}
gNames = llGetNotecardLine(Card2,gLine);
gLine++;
}
else
{
serving_data = FALSE;
}
}
}

touch_start(integer num)
{
if(serving_data) return; // Don't do anything till notecard reading is complete.

llDialog(llDetectedKey(0),"Please choose a sound:",names,dchannel);
start_listen(llDetectedKey(0));
}

listen(integer channel, string name, key id, string message)
{
llListenRemove(listening);
integer index = llListFindList(names,[message]);
llTriggerSound(llList2String(sounds,index),1.0);
}
}


Basically.. if line 0 in the sounds notecard is hi.wav, and line 0 in the names notecard is Hello, then by selecting Hello and retrieving the list index for that word (0), you can easily find the corresponding line in the other list from the notecard. It's basically a very flat database table.

Also.. I just wrote this here, it's untested, so I don't doubt for a second there could be typos and other mistakes throughout but this should get you on track at least.
Slayd Lemieux
Registered User
Join date: 9 Jul 2005
Posts: 29
Almost...
09-01-2005 16:05
Ok, well I think I've almost got it. Thank ya very much Gaz! Had most of it already written, except the last bit, but I was able to improve the rest as well with what you wrote.
Took a little doing, but got it to compile.

Here's my current problem. When I'm running the script, it seems to be adding the first two lines of the notecard just fine, after that (using the example below) the if(gline == query) seems to be reporting false. So I'm getting just two items added to the list, even though there are four, and then it skips to the next part of my script.
Slayd Lemieux
Registered User
Join date: 9 Jul 2005
Posts: 29
Still going
09-01-2005 21:04
Alright, got past the notecard reading. Gonna have to do some tests to see if I can make it fool-proof, or at least close too, heheh.

Now I'm stuck on the menus... they aren't popping up for me. Will keep working on it and keep the post updated.

Thanks for the help so far everyone! Feel like I'm getting my scripting feet under me :)
a lost user
Join date: ?
Posts: ?
09-01-2005 23:28
The problem with the dataserver is that it runs off by itself. I mean.. the actual dataserver is acting idnependantly from the script. The dataserver(key query, string data) event is just catching the information generated and sent by the data server to the object that requested information, in this case a notecard line.

You can't have a loop or a delay that waits for the dataserver to end before doing anything else because that loop will prevent the dataserver event from firing and catching the data from the server. So the only real way to read two or more separate notecards is to read one, wait for it to finish reading the first one by waiting for the EOF (End of File) data, and then starting to read the other notecard, and so on.

That is why I have a "serving_data" variable to set TRUE while it is reading data and FALSE when it has finished. Then if some other event, such as a touch, is triggered.. I ignore it if serving_data is TRUE by using a return statement.


Regarding the dialogs:
Make sure you are sending the llDialog() to the correct id. If the dialog is activated with a touch.. use llDetectedKey(0) then if you want a second menu to appear when the person gives their response. You will need to use the id from the listen event. Alternatively, you could make a global key which is set during the touch event.

Also.. the channel that the dialog uses is the channel the listen event needs to be listening on to catch the response.
Slayd Lemieux
Registered User
Join date: 9 Jul 2005
Posts: 29
Thanks!
09-02-2005 10:55
Thanks Gaz, you've been a great help! Absolutely correct also, hehehe.

Problem with the dataserving got corrected, I was misusing my if/else if/else's. Had to throw in some llOwnerSay's to track it down.

With the dialog menu I had to fix the key values. Since there's no touching going on in this version, had to use the owner and object keys.

All in all I think it came out pretty darn good. Just got to make it look snazzy now.

I do have a question still though. I have listens set up on 3 channels for it. They're all closed channels, and set to only recieve from the object itself, or the owner. Would this still create a hunk of lag, or since they're closed would it be negligble? More then willing to condense it to one listen, if the lag created would be nasty. I know we don't need more lag, heheh.

Thanks again Gaz! *salute*
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
09-02-2005 12:47
3 listens isn't too nasty, but it might be easier for your user(s) if it was just one.

Poseballs are the biggest abusers of listens...
Slayd Lemieux
Registered User
Join date: 9 Jul 2005
Posts: 29
Problem while testing
09-03-2005 13:30
Thanks Keknehv! Figured that was the case, but wanted some confirmation. Only one listen is actually used by the user, the other 2 are for the menus. I can cut that down to 1 now, I originally did it to make scripting it a bit easier(so I thought).

I'm having a problem with the reading of the sound files now. It seems that (no copy),(no modify) sounds arenn't being read right. The name in the notecard matches, but it's still returning File Not Found In Inventory.

Is there a reason for this, and if so, is there a work around?

This was one of the main reasons why I made it, we wanted a way to play sounds quick, and since (no copy)(no modify) don't show up for gestures, figured this would work.

Hope this won't be a plan killer, lol. Thanks!