Alternative to RecordSound Dialog Speech Control
If you are looking for an alternative to the RecordSound control or wondering how it works in the background here is an alternative.
ASPX Page (and Jscript)
First create a couple of semantic items on your .aspx page:
<speech:SemanticItem id="RecordedNameLocation" runat="server"/>
<speech:SemanticItem id="RecordedNameUrl" runat="server"/>
<speech:SemanticItem id="RecordedNameDuration" runat="server"/>
<speech:SemanticItem id="RecordedNameSize" runat="server"/>
<speech:SemanticItem id="SaveRecordedName" runat="server" AutoPostBack="True"/>
Description of the Semantic Items:
- RecordedNameLocation: will contain the temporary location of the recorded wav file made by the speech server.
- RecordedNameURL: on post back this variable will contain the URL to play the wav back to the caller.
- RecordedNameDuration: will contain the duration in milliseconds of the recorded name.
- RecordedNameSize: will contain the size of the wav file in bytes.
- SaveRecordedName: This is a semantic item we use just to post back and save the recorded name.
Then create a new RecordName QA:
<speech:QA id="RecordName" runat="server" Settings="RecordNameSettings" OnClientComplete="RecordNameComplete" ClientActivationFunction="RecordNameActivate">
<Answers>
<speech:Answer SemanticItem="RecordedNameLocation" XpathTrigger="/SML/@recordlocation"/>
</Answers>
<ExtraAnswers>
<speech:Answer SemanticItem="RecordedNameDuration" XpathTrigger="/SML/@recordduration"/>
<speech:Answer SemanticItem="RecordedNameSize" XpathTrigger="/SML/@recordsize"/>
</ExtraAnswers>
<Reco>
<Record Enabled="True"/>
</Reco>
<Prompt PromptSelectFunction="RecordNamePrompt" ID="RecordName_Prompt"/>
</speech:QA>
Description of RecordName QA:
- To enable recorded in a QA set the Record Enabled="True" in the Reco section. What happens with this QA is that the user's speech will be recorded instead of performing recognition.
- The path of the recorded file is returned in the SML instead of recognition results. However, this wav file will only exist in a temporary location only as long as the call is available. So, you are going to have to copy this file from the temporary location to a location of your choosing. The Temporary Audio File Location is configurable by a setting in the Telephony Application Services MMC snap in.
- The Answer control binds the recorded file location to the SemanticItem of an input control the same way it binds recognition results. The Answer.XPathTrigger value "/SML/@recordlocation" returns the recorded file location from the SML. I go ahead and gather some other data that comes back from the SML such as duration and size of the wav file.
- Note: Make sure in the RecordNameSettings we define later you set bargein="false". This produces an error if you have bargein set to true. This is because the TIM can not listen for reco and record at the same time.
When this RecordName QA finishes the wav file will be located under the Temporary Audio File Location on the Telephony Application Services box. We need to get this wav file to a directory under our own speech application. Your web server may be on the same box or it may be on a separate box. Either way we have to transfer the file. You copy this file using the file upload html object.
Place the following in your .aspx page just after the RecordName QA but before the </form> tag:
<input type="file" id="postedFile" runat=server>
Now, add your Jscript functions to the aspx file just after the </form> tag:
<script language="jscript">
function RecordNameActivate()
{
//put any activation logic here
return true;
}
function RecordNamePrompt()
{
//put any prompt logic here
return "Please record your name";
}
function RecordNameComplete()
{
var semanticItem : SemanticItem = RunSpeech.GetSemanticItem("RecordedNameLocation");
//save the recorded file location
document.all("postedFile").value = semanticItem.value;
//use this semantic item to post back and save off the file to the web server
doPostBack("SaveRecordedName");
return false;
}
//This function just toggles the text value of a semantic to get it to post back
function doPostBack( theSI:String):void
{
var semanticItem : SemanticItem = RunSpeech.GetSemanticItem(theSI);
if( semanticItem.value == "true"){
semanticItem.SetText("false", true);
}else{
semanticItem.SetText("true", true);
}
}
</script>
ASPX.CS Codebehind
We need to setup the postback function. The best way is to let Visual Studio do that for you. Following these steps:
- Go to the design tab of your .aspx page.
- Right click on the SemanticMap. Click Property Builder…
- Click on SaveRecordedName semantic item.
- Check the auto postback check box.
- Click the changed: dropdown list box and select <new> and select the default name of SaveRecordedName_Changed and click ok.
- Click Ok to save.
Open up your .aspx.cs code and find the SaveRecordedName_Changed function that was created for you:
private void SaveRecordedName_Changed(object sender, Microsoft.Speech.Web.UI.SemanticEventArgs e)
{
//Of course you want your own way of naming your file
string waveFileName = "RecordedName.wav";
//We save it to the root of this current virtual directory
string physicalPath = Server.MapPath(".");
//You have to add using System.IO; to the top of your .cs for this to work
string saveAsPath = Path.Combine(physicalPath, waveFileName);
postedFile.PostedFile.SaveAs(saveAsPath);
RecordedNameUrl.Text = @"./" + waveFileName;
}
At the top of your .cs page make sure you add the following for the Path object:
using System.IO;
Web.config
In your Web.config place this after your </system.web>:
*Note you have to place this in your Web.config in order for the RecordName QA to work.
<speechControlSettings>
//You may have other "globalStyle" settings for your prompts here
<speechControlSettingsItem id="RecordNameSettings">
<qa>
<prompt bargeIn="false" />
<reco beep="false" endSilence="2010" babbleTimeout="7000" maxTimeout="10000" />
</qa>
</speechControlSettingsItem>
</speechControlSettings>
Again, you have to set the bargeIn to false or you will get an error from MSS.
Tweak the settings here to your liking. Although, I could never get initialTimeout to work. I think that the endSilence is the same as the initialTimeout. Which is a bummer because I would like to have initialTimeout set to a long 5000 and endTimeout set to a short 1000, but the system just would not let me. Let me know if you figure this out.
Setting security permissions:
So, make sure you give write permissions to ASPNET in Windows XP or NETWORK SERVICE in Windows 2003 to your root folder of your virtual directory or you will get the following error:
Access to the path "c:\inetpub\wwwroot\YourSpeechApp\RecordedName.wav" is denied.
Test
Now, run this through TASIM or point your MSS at your application and you should see the RecordedName.wav file in the root directory of your virtual directory.