Introduction
Here are two simple
examples of SALT and X+V being used in a multimodal application.
Both SALT examples are from the SALT 1.0 specification but
"made safe", according to
http://www.saltforum.org/saltforum/downloads/SALT1.0.pdf
section 2.6.5 (A 'safe' voice-only dialog).
As for the voice-only case,
care needs to be taken to ensure the SALT examples work
properly. The VoiceXML form embedded in the X+V page
is inherently "safe": X+V interpreters must never
leave a dialog in a "hanging state". Note that,
for the multimodal case, if there is a problem with speech
the author can present a visual message. All the examples
shown here present an alert if there is a speech error.
The examples provided by the
SALT Programmer's Reference in the MSDN
Library site include an object needed to load the SALT
implementation into Microsoft Internet Explorer. This object
is also included with both SALT examples shown here.
|
Stock Ordering ("Safely")
Entering a From City and To City ("Safely")
SALT Forum Companies Back VoiceXML
Stock Ordering ("Safely")
This example is
a four-field stock ordering form. The SALT is larger
than the equivalent X+V, partially because the SALT author
had to write an FIA while the X+V author gets the VoiceXML
FIA for free. The author also must set the HTML fields
with the speech recognition results within a JavaScript
routine which is not reusable. Because the X+V <sync>
tag does this for the author automatically, the embedded
VoiceXML form within the X+V example is reusable. |
<html xmlns:salt="http://www.saltforum.org/2002/SALT">
<head>
<object id="SpeechTags" CLASSID="clsid:DCF68E5B-84A1-4047-98A4-0A72276D19CC"
VIEWASTEXT></object>
<title>Context Sensitive Help</title>
<script>
<![CDATA[
var focus;
function RunSpeech()
{
if (trade.stock.value == "") {
focus="trade.stock";
p_stock.Start();
return;
}
if (trade.op.value == "") {
focus="trade.op";
p_op.Start();
return;
}
if (trade.quantity.value == "") {
focus="trade.quantity";
p_quantity.Start();
return;
}
if (trade.price.value == "") {
focus="trade.price";
p_price.Start();
return;
}
document.getElementById("trade").submit();
}
function handle()
{
res = event.srcElement.recoresult;
if (res.value == "help") {
text = "Please just say ";
text += document.all[focus].title;
p_help.Start(text);
} else if (event.srcElement.id == "g_stock") {
document.getElementById("stock").value = res.value;
} else if (event.srcElement.id == "g_op") {
document.forms[0].op.options[res.value].selected = true;
} else if (event.srcElement.id == "g_quant") {
document.getElementById("quant").value = res.value;
} else if (event.srcElement.id == "g_price") {
document.getElementById("price").value = res.value;
}
}
function doNotUnderstand() {
text = "Please just say ";
text += document.all[focus].title;
p_doNotUnderstand.Start(text);
}
function procError() {
alert("Sorry, there was a speech error");
}
]]>
</script>
</head>
<body onload="RunSpeech()">
<salt:prompt id="p_doNotUnderstand" onerror="procError()"
oncomplete="RunSpeech"()" />
<salt:prompt id="p_help" onerror="procError()" oncomplete="RunSpeech()" />
<salt:prompt id="p_stock" onerror="procError()" oncomplete="g_stock.Start()">
Please say the stock name
</salt:prompt>
<salt:prompt id="p_op" onerror="procError()" oncomplete="g_op.Start()">
Do you want to buy or sell
</salt:prompt>
<salt:prompt id="p_quantity" onerror="procError()" oncomplete="g_quantity.Start()">
How many shares?
</salt:prompt>
<salt:prompt id="p_price" onerror="procError()" oncomplete="g_price.Start()">
What's the price
</salt:prompt>
<salt:listen id="g_stock" onreco="handle(); RunSpeech()"
onnoreco="doNotUnderstand()"
onsilence="doNotUnderstand()"
onerror="procError()">
<salt:grammar src="./g_stock.grxml" />
</salt:listen >
<salt:listen id="g_op" onreco="handle(); RunSpeech()"
onnoreco="doNotUnderstand()"
onsilence="doNotUnderstand()"
onerror="procError()">
<salt:grammar src="./g_op.grxml" />
</salt:listen >
<salt:listen id="g_quantity" onreco="handle(); RunSpeech()"
onnoreco="doNotUnderstand()"
onsilence="doNotUnderstand()"
onerror="procError()">
<salt:grammar src="./g_quant.grxml" />
</salt:listen >
<salt:listen id="g_price" onreco="handle();RunSpeech()"
onnoreco="doNotUnderstand()"
onsilence="doNotUnderstand()"
onerror="procError()">
<salt:grammar src="./g_quant.grxml" />
</salt:listen >
<form id="trade">
<input name="stock" title="stock name" />
<select name="op" title="buy or sell">
<option value="buy" />
<option value="sell" />
</select>
<input name="quantity" title="number of shares" />
<input name="price" title="price" />
</form>
</body>
</html>
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml
xmlns:vxml="http://www.w3.org/2001/vxml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xv="http://www.voicexml.org/2002/xhtml+voice">
<head><title>Context Sensitive Help</title>
<vxml:form id="RunSpeech">
<vxml:field name="vstock" xv:id="vstock">
<vxml:prompt> Please say the stock name.</vxml:prompt>
<vxml:grammar src="./g_stock.grxml"/>
<vxml:catch event="noinput nomatch help">
Please just say stock name. </vxml:catch>
</vxml:field>
<vxml:field name="vop" xv:id="vop">
<vxml:prompt>Do you want to buy or sell?</vxml:prompt>
<vxml:grammar src="./g_op.grxml"/>
<vxml:catch event="noinput nomatch help">
Please just say buy or sell. </vxml:catch>
</vxml:field>
<vxml:field name="vquantity" xv:id="vquantity">
<vxml:prompt> How many shares? </vxml:prompt>
<vxml:grammar src="./g_quant.grxml"/>
<vxml:catch event="noinput nomatch help">
Please just say number of shares. </vxml:catch>
</vxml:field>
<vxml:field name="vprice" xv:id="vprice">
<vxml:prompt> What's the price? </vxml:prompt>
<vxml:grammar src="./g_price.grxml"/>
<vxml:catch event="noinput nomatch help">
Please just say price. </vxml:catch>
</vxml:field>
</vxml:form>
<script ev:event="vxmlerror" ev:observer="bd1" declare="declare">
alert("Sorry, there was a speech error");
</script>
<script ev:event="vxmldone" ev:observer="bd1" declare="declare">
document.getElementById("trade").submit();
</script>
<xv:sync input="stock" field="#vstock"/>
<xv:sync input="op" field="#vop"/>
<xv:sync input="quantity" field="#vquantity"/>
<xv:sync input="price" field="#vprice"/>
</head>
<body id="bd1" ev:event="load" ev:handler="#RunSpeech">
<form id="trade">
<input name="stock" title="stock name" />
<select name="op" title="buy or sell">
<option value="buy" />
<option value="sell" />
</select>
<input name="quantity" title="number of shares" />
<input name="price" title="price" />
</form>
</body>
</html>
Figure 2: stock.x+v.html
<html xmlns:salt="http://www.saltforum.org/2002/SALT">
<head><title>Simple Mixed Initiative Dialog</title>
<object id="SpeechTags" CLASSID="clsid:DCF68E5B-84A1-4047-98A4-0A72276D19CC"
VIEWASTEXT></object>
</head>
<body onload="RunAsk()">
<form id="travelForm">
<input name="txtBoxOriginCity" type="text" />
<input name="txtBoxDestCity" type="text" />
</form>
<!-- Speech Application Language Tags -->
<salt:prompt id="askOriginCity" onerror="procError()">
Where would you like to leave from?
</salt:prompt>
<salt:prompt id="askDestCity" onerror="procError()">
Where would you like to go to?
</salt:prompt>
<salt:prompt id="helpAskOriginCity" onerror="procError()"
oncomplete="recoOriginCity.Start()">
For example, say Detroit.
</salt:prompt>
<salt:prompt id="helAskDestCity" onerror="procError()"
oncomplete="recoDestCity.Start()">
For example, say Detroit.
</salt:prompt>
<salt:listen id="recoOriginCity" onreco="procOriginCity()"
onnoreco="helpAskOriginCity.Start()"
onsilence="helpAskOriginCity.Start()"
onerror="procError()">
<salt:grammar src="city.xml" />
</salt:listen>
<salt:listen id="recoDestCity" onreco="procDestCity()"
onnoreco="helpAskDestCity.Start()"
onsilence="helpAskDestCity.Start()"
onerror="procError()">
<salt:grammar src="city.xml" />
</salt:listen>
<!�- scripted dialog flow -->
<script>
function RunAsk() {
if (travelForm.txtBoxOriginCity.value=="") {
askOriginCity.Start();
recoOriginCity.Start();
} else if (travelForm.txtBoxDestCity.value=="") {
askDestCity.Start();
recoDestCity.Start();
}
}
function procOriginCity() {
travelForm.txtBoxOriginCity.value = recoOriginCity.text;
RunAsk();
}
function procDestCity() {
travelForm.txtBoxDestCity.value = recoDestCity.text;
travelForm.submit();
}
function procError() {
alert("Sorry, there was a speech error");
}
</script>
</body>
</html>
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml
xmlns:vxml="http://www.w3.org/2001/vxml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xv="http://www.voicexml.org/2002/xhtml+voice">
<head><title>Simple Mixed Initiative Dialog</title>
<!-- VoiceXML -->
<vxml:form id="RunAsk">
<vxml:field xv:id="recoOriginCity" name="recoOriginCity">
<vxml:grammar src="city.xml"/>
<vxml:prompt>Where would you like to leave from?
</vxml:prompt>
</vxml:field>
<vxml:field xv:id="recoDestCity" name="recoDestCity">
<vxml:grammar src="city.xml"/>
<vxml:prompt> Where would you like to go to?
</vxml:prompt>
</vxml:field>
<vxml:catch event="nomatch noinput">
For example, say Detroit.
</vxml:catch>
</vxml:form>
<!-- sync's -->
<xv:sync input="txtBoxOriginCity" field="#recoOriginCity"/>
<xv:sync input="txtBoxDestCity" field="#recoDestCity"/>
<script ev:event="vxmlerror" ev:observer="bd1" declare="declare">
alert("Sorry, there was a speech error");
</script>
<script ev:event="vxmldone" ev:observer="bd1" declare="declare">
document.getElementById("travelForm").submit();
</script>
</head>
<body id="bd1" ev:event="load" ev:handler="#RunAsk">
<form id="travelForm">
<input name="txtBoxOriginCity" type="text" />
<input name="txtBoxDestCity" type="text" />
</form>
</body>
</html>
Figure 4: from.to.x+v.html
|