A PAGER Tag Parsing Method Example

A PAGER Tag starts with an opening corner bracket ‘<' and ends with a slash and corner bracket '/>‘. The resulting substring between the start and end is then split at the dash ”-” with the first substring being the name of the sub-system being targeted and the second half of the substring referencing names, lists, methods and parameters. This half of the substring is then Split at the “params=?” string. The first half of that split contains the comma delimited names of assets and methods to use and the second half of the split contains the parameters to be applied to the asset or method. The tagEventDuration is passed in after the TTS engine calculates an approximate time to speak the utterance. This can be useful for setting up pose to pose sequencing.


public void ParsePAGERTag (string pTag, float tagEventDuration) {
       //split the pTag string into the subsystem targeted and the variables used
       string [] baseData = pTag.Split('-');
       string subsystemStr = baseData [0];
       string subsystemVars = baseData [1];
       // split the subsystemVars at the params=? substring to yield the names of
gestures, poses, methods as well as the params to be used
       string [] ssData = subsystemVars.Split("params=?");
       string ssNames = ssData [0];
       string ssParams = ssData [1];
       //convert the ssNames into a single string or list of strings using a comma as
the delimiter
       string [] namesData = ssNames.Split(',');
       string [] paramsData = ssParams.Split(',');
       //find the reference Names, Lists and Methods of the namesData
       List refNames = new List();
       List refLists = new List();
       List refMethods = new List();
       for (int i = 0; i < namesData.Length; i++)  {
             if ( namesData [i].Contains("LIST") ) {
             //use a pre-defined List by the name of...
             string [] listData = namesData[i].Split(' ');//split by space
             refLists.Add(listData[1]);// Discard the LIST substring and grab the
name of the List
             } else if ( namesData [i].Contains("METHOD")) {
             //use the pre-defined method by name of
             string[] methodData = namesData [i].Split(' ');//split by space
             refMethods.Add(methodData[1]);
             } else {
             refNames.Add(namesData [i]);
             }
       }
       if ( subsystemStr == "FaceExpression" ) {
             HandleFaceExpressionTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if ( subsystemStr == "ArmsGesture" ) {
             HandleArmsGestureTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if ( subsystemStr == "LeftHandPose" ) {
             HandleLeftHandPoseTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if ( subsystemStr == "RightHandPose" ) {
             HandleRightHandPoseTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if ( subsystemStr == "BodyExpression" ) {
             HandleBodyExpressionTag(refNames, refLists, refMethods, paramsData,
             tagEventDuration);
       } else if ( subsystemStr == "LegsPose" ) {
             HandleLegsPoseTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if ( subsystemStr == "IKControls" ) {
             HandleIKControlsTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if ( subsystemStr == "PoseSequence" ) {
             HandlePoseSequenceTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if (subsystemStr == "GestureCtrl") {
             HandleGestureControllerTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if (subsystemStr == "HandPoseCtrl") {
             HandleHandPoseControllerTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if (subsystemStr == "FaceRigCtrl") {
             HandleFaceRigControllerTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       } else if (subsystemStr == "PoseSequencer") {
             HandlePoseSequencerTag(refNames, refLists, refMethods, paramsData,
tagEventDuration);
       }
       //tag has been consumed so can be removed from log List
       tagLog.Remove(pTag);
       }

The above example is the basic parsing of the tag whereupon it sends the results of the parsing to the appropriate subsystem handler method to further process the data. These methods sift the data to determine which particular method is to be called and what parameters to send to that method to have it execute the response. Generally the method will set up a pose or gesture to interpolate to over a specified time though you can certainly extend the functionality in any manner deemed conducive to your application.

The PAGER tag as with the SSML tag is stripped from the utterance text with the SSML controlling speech synthesis and timing. The PAGER tag controls the motion synthesis and timing of the Avatar gesture expressions. It then logs the tag and event duration adding the PAGER tag to a tagLog List and passing the first member as well as event duration to the parsing method as in the example above. The parser consumes the tag and removes it from the tagLog List. Within the Handler methods if the tagLog List has a Count greater than 0 it will pass the next tag at tagLog[0] into the parsing method and consume it until it exhausts the List. The eventDuration is stored in a public field and will only be altered as a new Tag Logging event occurs.