How It Works
The following section is devoted to the architecture of the system. We start with an explanation of common user controls and common script files. Then we will go into detail on the browse feature, which provides a good encapsulation of many of the programming techniques used throughout the application. Finally, we'll review some of the coding conventions and practices we used as best-practice techniques for development.
Common Files: User Controls
Two ASP.NET user controls are included on almost every page in our application. Together they encapsulate much of the functionality of the site, and each deserves discussion. Like designing Web applications, user controls in the ASP.NET Speech SDK can be used to provide a consistent user experience while saving a great deal of code.
The GlobalSpeechElements user control is required on every page of the application (except for Goodbye.aspx
, which do little more than read a prompt and transfer the user away). It contains the main stylesheet that defines common properties of the controls used throughout the application, as well as global command controls and common script files that provide client-side functional components.
- MainStyleSheet: The Speech SDK style control is a powerful way of defining global application settings and assigning globally scoped functionality. In the Commerce sample we have four different styles:
- BaseCommandStyle: This style is applied to all command controls. Its one attribute sets the AcceptCommandThreshold at .6, meaning that any command must be recognized with at least a 60 percent confidence rating to be accepted.
- GlobalCommandStyle: This style is applied only to the six global styles contained in GlobalSpeechElements. This style inherits the attributes of BaseCommandStyle and adds a dynamically set scope attribute. We want global commands to apply to all controls on any page they are included in, so we set the scope to be the parent page's ID at runtime.
<command scope='<%# GetParentPageID() %>'></command>
- BaseQAStyle: This style is applied to all QA controls that accept user input (QA controls which do not accept user input are called "Statements" and use the StatementQA style below). In addition to setting timeout and confidence thresholds, this style also defines the OnClientActive event handler for all QA controls. HandleNoRecoAndSilence is a JScript event handler that monitors a user's unsuccessful attempts to say a valid response and transfers the user to customer service after enough unsuccessful events. It is described in the section on Common Script files below.
- StatementQA: For QA controls that do not accept user input, we want to disable BargeInthe act of interrupting a prompt before it ends with a responseand turn on PlayOnce, which ensures the prompt is not repeated. Normal QA controls are activated when their semantic item is empty; since Statement QA controls have no semantic item, the control would be played over and over again if PlayOnce was turned off.
- Global Commands: The global commands in GlobalSpeechElements (described in the Navigation Design section) each have associated with them a command grammar file that defines how the command is activated.
Commands fall into two categories: those that affect the current prompt, such as HelpCmd, InstructionsCmd, and RepeatCmd (see Figure 5), and those that trigger an event (RepresentativeCmd, GoodbyeCmd, MainMenuCmd). For the former, the prompt function looks for a particular Type value in its lastCommandOrException parameter and creates an appropriate command. For the latter, the command's associated OnClientCommand event handler is executed.
|Figure 5: One category of global commands affects the current prompt.|
- Common Script File Includes: GlobalSpeechElements is an ideal place to include references to all global script files. These files constitute all global client-side event handlers and prompt generation/formatting routines for the application. Since they are included in the control, individual pages can rely on their availability without explicitly including them.
<script type="text/jscript" src="routines.js"></script>
<script type="text/jscript" src="speech.js"></script>
<script type="text/jscript" src="CommerceV.js"></script>
The SelectableNavigator user control is used on any page that needs a dynamically generated list of items from which the user may select. While the Navigator application control included in the Speech SDK can read a list of items, it does not allow the user to select one of the items in the list. The SingleItemChooser application control does allow the user to select an item, but it is unwieldy for large lists. The SelectableNavigator contains a Navigator application control, as well as a QA control and a Command control (see Figure 6
|Figure 6: The SelectableNavigator control contains a Navigator application control, a QA control, and a Command control.|
- InitialStatement: The prompt of the InitialStatement QA is used to tell the user something about the list. Originally, we had this initial statement as part of what the navigator says for its first item. However, if the user mumbles, this initial statement and the first item are lost. Since we wanted to ensure the user heard the first item, we separated the initial statement from the first item. This way, even if the user mumbles during the initial statement, they will still hear the first item after the system recovers.
- TheNavigator: The Navigator takes care of the tasks associated with reading and navigating through the list of items associated with the control.
- SelectCmd: This command, scoped to TheNavigator, allows the user to select an item. The grammar for this command may be specified dynamically by setting the IsDynamic property of the SelectableNavigator to true (the default). The grammar always contains at least "Select" and "That one" to select the current (most-recently read) item but if this flag is set, the grammar also contains the items found in the first field specified in the DataHeaderFields property. Thus, if the user is on the first item and says the name of the fifth item, the fifth item is selected.
Since user controls have no designer support, all properties are set programmatically in the code-behind file. In addition, this means dragging the user control onto a page does not add additional speech mark-up to the page as does dragging one of the Speech SDK's controls, such as a QA, onto the page. This isn't normally a problem since you will usually want other speech controls on the page, such as a semantic map. However, something else you don't automatically get is a prompt function file to keep the prompt function for the SelectableNavigator. Again, this isn't normally a problem so long as there are other controls on the page that will want a prompt function. For instance, using the Property Builder for a QA to add a prompt function will automatically add a prompt function file if one does not already exist for the page. After doing so, you may add a prompt function to that file yourself for a SelectableNavigator on the same page.
Because the Speech SDK is very client-side-heavy, there are two client-side JScript functions to write to handle two events fired by the SelectableNavigator, OnCancel
- OnCancel: The SelectableNavigator fires this event if the user says "cancel" while in the SelectableNavigator. Since the Navigator's built-in cancel command deactivates the Navigator, RunSpeech will skip the SelectableNavigator during subsequent iterations.
- OnSelect: The SelectableNavigator fires the event if the user selects an item, either by saying "select" or the name of an item if IsDynamic is true. Return true from this handler to deactivate the SelectableNavigator.
The client- and server-side properties and methods exposed by the SelectableNavigator are documented in SelectableNavigator.html.