Game Development Community

AudioProfile Datablocks not always ready for clients

by Jim Rowley · in Torque Game Engine · 02/05/2004 (11:09 pm) · 15 replies

I'm not completely sure this is a torque 'bug', but nobody has answered me in the Engine forum yet, so I thought I'd post a reference here as well.

www.garagegames.com/mg/forums/result.thread.php?qt=16006#121327

Further tests I'm doing seem to show that Torque does have a potential for sound errors with AudioProfile datablocks referencing AudioDescription datablocks on clients.

I'm currently trying a hack which unpacks the description datablock ID into mDescriptionObject like so:

if (stream->writeFlag(mDescriptionObject))
stream->writeRangedU32(packed ? SimObjectId(mDescriptionObject) : mDescriptionObject->getId(), DataBlockObjectIdFirst,DataBlockObjectIdLast);

I've also moved Sim::findObject(id, mDescriptionObject) out of AudioProfile::unpackData() and into AudioProfile::preload() like so:

if (!server)
Sim::findObject(SimObjectId(mDescriptionObject), mDescriptionObject);

For my hack to work, I had to alter the test for client profiles that happens in AudioProfile::onAdd() in order to avoid occasionally trying to call getId() from a mDescriptionObject which was unpacked as an Id already... I wound up adding the boolean field 'packed' you see above to AudioProfile, just like GameBaseData does, to let the system know whether or not we're dealing with an id or a real object pointer at any time. This can be tested in onAdd to be sure we're dealing with an object pointer and tested in packData as well, to see if we should be sending over an id or a true pointer depending. Oh yeah, and finally, I also made the same changes to use temporary ID's for mSampleEnvironment to help it work one day... (I basically copied the way GameBaseData handles referenced datablocks).

So far, this hack seems to have corrected for any problems of referencing an AudioDescription prior to the client having received the SimDataBlockEvent which adds it. Let me know if anyone wants the c++ files posted.

#1
02/06/2004 (1:14 am)
Hmm.. i wonder if thats what I'm having an issue with.

Ive got a problem with the client connecting and getting invalid packets. But its in an audioprofile datablock that its doing it.

I'll have to have a look.
#2
02/06/2004 (1:16 am)
If its related to this problem I've witnessed, you ought to be able to check tree() on a client and look at the Id's for the audiodescription and the audioprofile... if they're consecutive or very close, you may be experiencing it. Also, if the AudioProfile on the client winds up with NULL for its description, then its probably this error.
#3
02/06/2004 (5:52 am)
What happens with the sound then Jim ?
I have over 20 fx sounds and 10 serverplaying sounds and i dont hear any differns between the server and the client.
and i use NULL descriptions on the emitters.
#4
02/06/2004 (6:59 am)
I have noticed the same issue.. if you created a audioprofile within the engine scripts and reference a audiodescription client side things go nuts. After about 3 - 4 seconds of being in a mission the mission will frezze and the sound will sound like a 45 record that is stuck in the same spot..

-Ron
#5
02/06/2004 (7:13 am)
Ron

I think this is the headversions audio problem
I used that to get ogg vorbis but i changed back to my old one.
when you mentioned that the sound was freezing then the bell ringed.
i only got this problem from the head.
#6
02/06/2004 (9:10 am)
Back to your old one? as in TGE 1_1_2 ?
-Ron
#7
02/06/2004 (10:23 am)
Well, for me, the sounds are just not available on the client because the audioProfile contains a null entry for the audioDescription after unpacking it on the client. It only happens when I have no or few datablocks defined between the description and the profile which refers back to it. Code like this would most likely show me the problem:

datablock AudioDescription(AudioLongRange3d)
{
volume = 1.0;
isLooping= false;
is3D = true;
ReferenceDistance= 50.0;
MaxDistance= 4000.0;
type = $SimAudioType;
};
datablock AudioProfile(FlyingVehicleExplodeSound)
{
filename = "~/data/sound/explode.wav";
description = "AudioLongRange3d";
preload = true;
};

If I have other datablocks defined between the two, there is usually enough time for the client to receive the audio description dataBlockEvent before it tries to create the audio profile, and then the problem is not noticed.

Consequently, I've moved my AudioProfiles into script which executes a little later on, and then everything worked ok, but I still wanted to try my hack because there are times where I may not want to think about how many datablocks are defined between the two... For example, in onServerCreated(), I might have these two lines:
exec("./audioprofiles.cs"); //<--audioDescriptions are in here
exec("./flyingVehicle.cs"); //<--audioProfiles are in here

With that code, I still had my problem because the audioProfile still wound up with a client Id only one away from the description. Hope I've conveyed this problem now... :)
#9
04/24/2004 (1:18 pm)
The problem is that the audiodatablock is searching for the object in the unpack() function, but when unpacking the object may be not created yet, the correct way is to store the read Id and search for it only on onAdd() function.
#10
04/11/2005 (1:07 pm)
I just wanted to corroborate this bug with my own experience (a full year after you guys ran into it.)

For my game, client sounds (vehicle engine sounds, specifically) weren't working, although their corresponding objects on the server were making sounds just fine. I tracked the error down to the client's audioprofile containing a NULL audio description.

I tried all sorts of hacks to get it to work, and I ended up trying to declare a new audio description and load it in when one wasn't there. This solution worked for about 20 seconds, then the sound stopped again. I guessed it was because a network update re-loaded the null data.

Anyways, like someone above suggested, I simply placed a couple of other non-related datablocks between the audio description and the audio profile that uses it. I haven't tested the "minimum", but 8 datablocks seem to be fine for me.
#11
07/06/2006 (10:57 am)
Thank you guys for this, was running into the same problem.

just stored the id then tried to find it in the onAdd like Marcelo suggested. works great.
#12
07/10/2006 (5:27 pm)
@Clint or Marcelo, could you post a sample? thx
#13
07/11/2006 (1:45 am)
Hi Desmond, sure thing...I dont have the code changes in front of me, but if I recall correctly it was something like this:

1. AudioProfile::unpackData(BitStream* stream)

in the section where it grabs the description, it used to look like this:
// audio datablock:
   if (stream->readFlag()) {
      SimObjectId id = stream->readRangedU32(DataBlockObjectIdFirst,
                                             DataBlockObjectIdLast);
      Sim::findObject(id, mDescriptionObject);
   }

I left this the same, but added a
mDescriptionObjectID = id; in there, like so:

// audio datablock:
   if (stream->readFlag()) {
      SimObjectId id = stream->readRangedU32(DataBlockObjectIdFirst,
                                             DataBlockObjectIdLast);
      mDescriptionObjectID = id;
      Sim::findObject(id, mDescriptionObject);
   }


then in the bool AudioProfile::onAdd() function,

right before it checks for the description object here:
// if this is client side, make sure that description is as well
   if(mDescriptionObject)

add something like this:

if(mDescriptionObjectID )
{
Sim::findObject(mDescriptionObjectID , mDescriptionObject);
}

then after this code it will check for the description object like it did before.


and of course in AudioProfile::AudioProfile()
set mDescriptionObjectID = 0;

And add mDescriptionObjectID to the AudioProfile class in AudioDataBlock.h


note, again I'm not testing or looking at my actual changed code right now, just looking at some tge 1.3 code, but I think that's what I did, and I hope you'll get the idea of the fix from the code either way.

best of luck
#14
10/15/2006 (6:56 pm)
Thanks for posting this fix guys, it does work and solved one of my many audio problems.
#15
02/07/2007 (6:27 pm)
I tried Clint's code change, but as soon as I start the engine, it crashes. Is there some other code change that I missed?
thanks