asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search








Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Introduction to the .NET Speech SDK
By Robert Chartier
Rating: 3.6 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article

    Introduction

    Even though the .NET Speech SDK is still in beta (2), exploring it will show what Microsoft has in store for us in the full release. To run the SDK, the .NET Framework SDK and the .NET Speech SDK beta must be installed. This entire article uses Visual Studio .NET 2002 (VS .NET) for application development. First, this article will cover Speech Application Language Tags (SALT), the foundation of this SDK. Next, we will enter a high-level overview of the actual SDK and quickly run through most of the controls and some of their properties in order to familiarize you with the whole SDK. Finally, there will be a demonstration of how to create a basic speech-enabled Web user control.

    After finishing this article, you should feel comfortable with developing your own controls and adding speech capabilities to applications.

    Overview of SALT

    SALT is essentially Extensible Markup Language (XML). More specifically: "Speech Application Language Tags (SALT) are a lightweight set of extensions to existing markup languages, in particular HTML and XHTML that enable multimodal and telephony access to information, applications and Web services from PCs, telephones, tablet PCs and wireless personal digital assistants (PDAs)." (See http://www.saltforum.org/faq.asp)

    For more information, read over the FAQ published by the SALT Forum at the URL listed above.Don't worry too much about the full SALT specification because Microsoft has provided a programmatic interface through a few controls that emit the appropriate tags. In the next section we will cover most of these controls.

    Within the SALT specification there are a few sections about the specific needs of speech-enabled applications. Some of these needs and their related SALT section are as follows (or see http://www.saltforum.org/regVerify.asp):

    1. Speech Output:
      This is done via the <prompt> tag and is used to indicate the content of audio output. There are three ways to provide the content of these prompts:
         i. Inline or referenced text
         ii. Variable values at render time
         iii. Links to audio files (.wav, etc.)

      For more information on the <prompt> tag and its features, refer to section 2.1 in the SALT 1.0 specification.

    2. Speech Input:
      Speech input is done via the <listen> tag and is used for speech recognition, audio recording, or both. When using this tag for speech recognition, you must also specify one or more <grammar> elements, which contain possible user input values. When using it for audio recording, a <record> element is needed. And finally, when the application needs to simultaneously record and recognize speech, use one or more <grammar> elements with a single <record> element.

    3. DTMF Input:
      This is the dual-tone multi-frequency (DTMF) control in the Speech Tab in the Toolbar. DTMF composes the audible sounds you hear when you press keys on your touch-tone phone. In DTMF there are 16 distinct tones. Each tone is the sum of two frequencies, one from a low and the other from a high-frequency group. There are four alternative frequencies in each group.

      In the context of this article we have the ability to listen for <dtmf> input from the user. The <dtmf> tag is essentially the same thing as the <listen> tag, except it can process DTMF input. This is useful if you are building telephony applications that are accessed from speech-enabled browsers (with or without a GUI) on wireless telephone devices. Notice, in the case of <dtmf> input, your <grammar> will simply be a list of the possible options that a phone offers -- digits 0-9, *, #, and A-Z.

    This is enough information to enable you to explore the SDK and see how it can be used to create speech-enabled ASP.NET applications.

    Introducing the ASP.NET Speech SDK

    This section explores the SDK at a higher level and offers an explanation of available controls and properties. In the SDK, there are two divisions of available controls: speech controls and speech application controls.

    Speech Controls

    Speech controls are really what most of us will use when creating speech-enabled applications. They typically relate directly to the actual SALT specification, emit very specific SALT-compatible markup, and allow you to produce this SALT markup at a higher level. Speech controls can be divided into two typical uses, ones with and ones without a graphical user interface (GUI).

    The first (multimodal) type is an application that does have a GUI. For example, your client will hit a Web page with his browser and interact with that page with the keyboard, mouse, or speech-enabled controls.

    The second (voice-only) is an application where no GUI support is available. The end user will navigate the site without a mouse. He uses only speech and DTMF tones to navigate.

    It is important to remember that these controls in the SDK actually perform a browser check and emit specific SALT tags, depending on the capabilities of the browser.

    Speech controls are divided into several major controls and properties. Let's briefly explore eight of them.

    1. QA Control: This is the main Question Answer (QA) control within the SDK. It allows us to define a single interaction with the user. A single interaction consisting of:    a. Prompting users;
         b. Recognizing their response; or
         c. Binding that response to a specific control on the page.

      This control allows the developer to specify all of the needed requirements for this interaction, including such things as prompts, grammar, and processing the results of the recognized response.

    2. Prompt Property: During the single interaction with the user, the user must be presented with a list of available options, or instructions on how to proceed. The Prompt property provides an audible method for providing these instructions. That is, it allows the developer to specify prompts for the user to hear and respond to. This control follows the requirements of the SALT specification because it allows for prompts to be provided in the three main formats:
         i. Inline or referenced text
         ii. Variable values at render time
         iii. Links to audio files (.wav, etc.)

    3. Reco Property: This property allows for the author to specify how the recognition is going to be performed. The primary attribute for this is the Grammar property, which is SALT-specific markup. The SALT engine uses this grammar to handle the responses from the user. It also contains routines to handle recognition errors and such.

    4. Answer Property: Once the application has recognized the user's input, it must know what to do with that response. This is where the Answer Property fits in. It defines how we can handle the results of the recognition.

    5. SemanticItem Controls: These controls are responsible for linking the QA answers to the actual input controls. Once the recognition is performed, the text is placed into the "target" for the SemanticItem to confirm and bind. This confirmation and binding may be done on the client or server.

    6. CompareValidator Control and
    7. CustomValidator Control: These controls allow developers to specify voice-only validation results. They allow us to provide validation feedback to the user when there is no GUI to send a message to.

    8. Command Control: This allows us to define more global speech-handling items. For example, if you create a global command "help," use the Command Control to allow your application to handle the "help" response from the user globally in the application.

    Speech Application Controls

    These controls are a combination of one or more of the speech controls described above. Authors can take advantage of these prebuilt and useful controls in their applications. Essentially, Microsoft has determined that there are a few controls that will be widely used in our applications today. It took that list and created a control based on each so that we do not have to replicate them over and over in our individual applications. In the future, it would be wise for you to further investigate these controls to see what is available. For simplicity purposes, I chose not to cover these further. Check the help documentation that ships with the SDK.

    Demo: Getting a User's Input

    Our demonstration is a fairly simple example of creating a speech-enabled Web user control. It will allow the user to choose an employee from a drop-down list (or verbally say a name), and it will then present that employee's profile. The employee list is a fixed group of people stored in an XML file. As we work through this demonstration, notice that I first set up the control without any speech-enabled portions. Once I get the functionality working, I then add the speech plumbing. Doing things this way allows me to first focus on functionality and then the additional interaction.

    Section 1 -- Basic Functionality

    Step 1. Let's start by creating a C# ASP.NET Web application at the location http://localhost/SaltProfiles.


    Figure 1.0 Creating the Project

    Step 2. Once VS .NET sets up the project, we will create a new Web user control. This is done by right-clicking the "SaltProfiles" project in the Solution Explorer and choosing "Add", "Add New Web User Control". I gave mine the name "ProfileViewer."

    Step 3. We need a drop-down list to display the current employees available. Add a standard "DropDown List" from the "Web Form" section in the Toolbox. Rename it "empDDL". Make sure that this is in the "ProfileViewer.ascx" designer.

    Step 4. Add a panel to display the complete user profile, which contains a table with labels for the employees' characteristics. See Figure 1.1 for the final product.


    Figure 1.1 The User Control without Speech Support

    Step 5. Load up our empDDL list with all of the available employees in our Employee XML. Figure 1.2 contains the current Employee XML document.


    Figure 1.2 EmpInfo.xml

    The structure of this XML document will remain fixed and only "user" nodes will be added and removed, depending on new hires/fires, etc. Consequently, we can use the serialization feature within .NET Framework to automatically import this XML document into a useable class.

    For more information on serialization, read my previous article on the topic at http://www.15seconds.com/issue/020903.htm. The deserialization in this demo is slightly different than what I show you in the serialization article, but the idea is just the same, taking an XML document and converting it to a specific Type (or class).

    We need to use our XML document to generate a Type representation of our XML document. The XSD.exe tool that ships with the .NET Framework SDK allows us to do just that. It is available at the DOS command line. There are two commands that we need to perform with XSD.exe in order for it to give us a Type. The first is to generate a schema based on the given XML (EmpInfo.xml) document

    
    xsd EmpInfo.xml
    
    
    and then to take that generated schema and convert it into a Type
    
    xsd EmpInfo.xsd /c
    
    

    Figure 1.3 Using the XSD.exe in the Command console

    After generating a Type, let's include that, along with our XML and XSD, into our project. This is done within the Solution Explorer by choosing "Show All Files" at the top of the Solution Explorer area, and then selecting all of "EmpInfo.cs", "EmpInfo.xml", and "EmpInfo.xsd", and right-clicking and choosing "Include In Project".

    Take time now to explore both the generated XSD and CS file. Notice that in the CS file there are actually two generated classes, one to represent the actual user and the second to represent a collection of users. We will need to use both of these in our demo. One change I made in the CS file was to add our "SaltProfiles" namespace, just for better organization. You can review the EmpInfo.cs file included with the download for this article if you do not understand.

    As I mentioned above, we are doing this so we can automatically deserialize the XML document into a Type (class), which is easier for us to use. We need to create a method that will allow us to perform that deserialization.

    
    private userdata GetEmployeeData() {
    	SaltProfiles.userdata ud;
    	if(Session["ud"]!=null) {
    		ud=(SaltProfiles.userdata)Session["ud"];
    	} else {
    		System.Xml.Serialization.XmlSerializer serializer = new 
    System.Xml.Serialization.XmlSerializer(typeof(SaltProfiles.userdata));
    		System.IO.TextReader reader = new 
    System.IO.StreamReader(Server.MapPath(EmployeeData));
    		ud = (SaltProfiles.userdata)serializer.Deserialize(reader);
    		reader.Close();
    		Session.Add("ud", ud);
    	}
    	return ud;
    }
    
    
    In this code we use the session object for a caching mechanism. This could easily be changed to the application object or any other suitable mechanism. It is simply used to store the deserialized class so that we do not have to continuously perform the deserialization each time it's needed.

    The main portion of the code above is within the "else" block of the code. It first creates a serialization object based on the type that we generated. Then it needs to read in the XML document, so it creates a TextReader. And, finally, the serializer uses the reader to pull out the userdata object. As you can see, it is very easy to create a fully typed class based on a simple XML document.

    As an alternative, you could have easily used the XML processing classes within the Framework, along with XPath, and pulled the relevant data out of it. I prefer the above method, with no messy XPath to worry about.

    With a collection of employees available for our application, let's use it to load up the drop-down list (DDL).

    
    if(data==null) data = GetEmployeeData();
    
    foreach(SaltProfiles.userdataUser user in data.Items) {
    empDDL.Items.Add(new System.Web.UI.WebControls.ListItem(user.name, user.name));
    }
    
    
    Step 6. Once the user chooses a name in the drop-down list, we want it to automatically post back to the server and for the application to display the profile of that selected user. This is easily accomplished in a few quick steps. First, set the AutoPostBack property for the empDDL to "True". This will allow the list to automatically post back to the server. Next double click the drop-down list, which should take you to the event handler for when the Selected Index is changed.

    Within our event handler we will first grab the text value for the selected item. This is done by using the "SelectedItem" property on the empDDL. We will then take that value and scan the list of employees we have cached in the session, and find the selected employee. Next, if we find a user, we will simply load up the value labels in our panel and make that panel visible. Here is the source:

    
    private void empDDL_SelectedIndexChanged(object sender, System.EventArgs e) {
    	System.Web.UI.WebControls.ListItem selItem = empDDL.SelectedItem;
    	SaltProfiles.userdataUser user = FindUser(selItem.Value);
    	if(user!=null) {
    		Panel1.Visible=true;
    		nameLabel.Text=user.name;
    		System.DateTime bday = System.DateTime.Parse(user.birthdate);
    		System.TimeSpan ts = new System.TimeSpan(System.DateTime.Now.Ticks-
    bday.Ticks);
    		this.ageLabel.Text=Convert.ToString(Math.Round(ts.TotalDays/365,0));
    		pictureImage.ImageUrl="/15seconds/SaltProfiles/images/"+user.image;
    	}
    }
    private SaltProfiles.userdataUser FindUser(string username) {
    	foreach(SaltProfiles.userdataUser user in data.Items) {
    		if(user.name==username) return user;
    	}
    	return null;
    }
    
    
    With that last piece added in, we now should have a functioning application. The drop-down list should populate with the employee list, and a user can choose which profile to display. Don't forget to click and drag your user control onto the Web Form designer so that it will be used on that form.

    Section 2 -- Adding Speech

    This section involves using the .NET Speech SDK so the user can optionally speak the name of the employee whose profile he wants to view. It builds on the previous code and adds in speech functionality.

    Step 1. In order to use the Speech SDK within VS .NET, we must first add the reference to the project. Right click the project, and choose "Add Reference", then hit the "Browse" button. Next, navigate to the folder in which you have installed the SDK. Mine is located at:

    "C:\Program Files\Microsoft .NET Speech\SpeechControls\v1.0.2826.0\ Microsoft.Web.UI.SpeechControls.dll".

    Make sure you choose the "Microsoft.Web.UI.SpeechControls.dll" and not the file "Microsoft.Web.UI.SpeechControls.ApplicationControls.dll". Since we are not using the Application Controls (described above), you do not need to add this reference.

    Step 2. You should see a "Speech" section in the VS .NET Toolbox. Here are the new speech controls. Let's add a new QA control to our user control by clicking and dragging it onto our form. If you choose that QA control and view its properties, you will notice two links, one for "Property Builder ..." and the other "Manage Prompt Databases ...". View both of them and see what they allow you to do with the QA control.

    Step 3. With a QA control available, let's set it up for use. First change the "OnClientComplete" and "OnClientListening" properties to "EndMultiModalInteraction" and "BeginMultiModalInteraction", respectively. These are the names of two JavaScript methods provided to you in the "speechInteraction.js" file and included with the download that was shipped with the SDK originally.

    Expand the Reco section within the properties. Notice this is where we set up the speech-recognition properties, which will happen on the client. These are the settings I used:

    BabbleTimeout=10000
    EndSilence=1000
    InitialTimeout=3000
    MaxTimeout=30000
    Mode=Automatic
    StartElement=micIcon
    StartEvent=onclick
    
    All of these properties are listed in detail in the help that ships with the SDK. Please refer to it for a full explanation. The last two items are the important factors; I will explain them in Step 4.

    The last step with the QA control is to add the SALT specification grammar tags. As mentioned above, we have a few different ways to load up the grammar, and one of these methods is to be able to specify the tags at runtime, meaning we can load up the grammar when the page loads. I have used the same EmpInfo.xml document that is available to me (an in-house corporate employee listing can be used from my company's internal documents, for example) and created an XSL stylesheet to transform the XML into the appropriate grammar tags we need.

    Next, I have created a method that will apply the XSL with the XML to produce our grammar:

    
    public string Transform(string xml, string xsl) {
    
    	System.IO.StringWriter sResult = new System.IO.StringWriter();        
    	System.Xml.XmlDocument docXml = new System.Xml.XmlDocument();
            
    	System.Xml.XmlDocument docXsl = new System.Xml.XmlDocument();
    	System.Xml.Xsl.XslTransform xslTransform 
    = new System.Xml.Xsl.XslTransform();
    	docXml.LoadXml(xml);
    	xslTransform.Load(xsl);
    	xslTransform.Transform(docXml, null, sResult);
    	return sResult.ToString();
    
    }
    
    
    (See the download package for full source code.)

    Final grammar output:

    Step 4. Triggering the page to begin speech recognition is initiated by an icon. In our demo, a microphone icon is set up to capture the onClick event. <IMG id="micIcon" alt="" src="images/mic.ico">

    Notice its "id" attribute is the same as the "StartElement" in Step 3, and it is its client id (not its server-side ID). Also notice that I did NOT specify an "onClick" attribute; the speech controls will do this for me.

    Step 5. In the "Speech" section in VS .NET's Toolbox, click and drag a new "SemanticMap" onto our user control's designer and make sure its ID is "SemanticMap1". Choose the "SemItems" collection in the properties for this control. Figure 2.0 below shows the properties that I set for this control.


    Figure 2.0 SemItems Properties

    Notice the TargetElement is the server-side name for the drop-down list. This allows us to bind this SemanticItem to the drop-down list, more specifically to its "value" attribute.

    Step 6. The last step is to bind the QA control to the SemanticItem control through the Answer Property within the QA control. In the properties for the QA control, there is an "Answer" Collection. Create a new answer with the following attributes:


    Figure 2.1 Answer Properties

    Notice that the property "SemanticItem" is the server-side name of the SemanticItem we previously added. Also notice the "XpathTrigger" is the node from within the grammar output that we are using to determine our rules for this answer. This allows you to use more than one grammar rule per XML file. Now that they are bound together, our control is finished. For the final product of the complete solution take a look at the solution within the downloadable source code.

    Conclusion

    This article contains enough detail to enable start using the .NET Speech SDK to create your own SALT-based speech enabled controls.

    Note that this SDK is focused on ASP.NET; therefore, there is no WinForm support. Also, free-speech dictation is not supported. For these items you still may need to use an alternative, such as the Microsoft Speech SDK 5.1 (see http://www.microsoft.com/speech/download/SDK51/).

    Also, to view the application, the client must install the Internet Explorer Speech add-in if the Speech SDK is not already loaded on a machine.

    References

    More information can be found at:

    http://www.microsoft.com/speech/
    http://www.microsoft.com/speech/download/SDK51/
    http://www.saltforum.org
    http://www.saltforum.org/downloads/SALT1.0.pdf
    http://www.saltforum.org/implementation.asp

    About the Author

    Robert Chartier has developed IT solutions for more than nine years with a diverse background in both software and hardware development. He is internationally recognized as an innovative thinker and leading IT architect with frequent speaking engagements showcasing his expertise. He's been an integral part of many open forums on cutting-edge technology, including the .NET Framework and Web Services. His current position as vice president of technology for Santra Technology (http://www.santra.com) has allowed him to focus on innovation within the Web Services market space.

    He uses expertise with many Microsoft technologies, including .NET, and a strong background in Oracle, BEA Systems, Inc.'s BEA WebLogic, IBM, Java 2 Platform Enterprise Edition (J2EE), and similar technologies to support his award-winning writing. He frequently publishes to many of the leading developer and industry support Web sites and publications. He has a bachelor's degree in Computer Information Systems.

    Robert Chartier can be reached at rob@santra.com.

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Other Articles
    Apr 21, 2004 - Creating a Web Custom Control
    Conrad Jalali shows how to build Web custom controls by creating one that displays checkboxes in a categorized, hierarchical view.
    [Read This Article]  [Top]
    Mar 15, 2004 - Creating a Popup Date Picker
    Conrad Jalali shows how to extend the functionality of the ASP.NET Calendar control to remove some of the annoying postback delays that occur when populating a text box with a date from a popup calendar.
    [Read This Article]  [Top]
    Oct 23, 2003 - Creating a Custom .NET Web Control With Events
    This article covers some of the essentials of building reusable Web controls. Learn how to create a Web control and its custom events and event arguments, as well as how to use the control properly within a page.
    [Read This Article]  [Top]
    Aug 12, 2003 - Creating a Generic Pager Control
    ASP.NET provides only one control that supports paging, the DataGrid. Tomasz Kaszuba shows how to build and implement a custom pager for different controls that change depending on the data source or presentation.
    [Read This Article]  [Top]
    Jun 10, 2003 - Hosting .NET Windows Forms Controls in IE
    Windows Forms within Web pages work in a manner similar to Java applets. Thiru Thangarathinam shows how to host Windows Forms controls in Internet Explorer and how to utilize .NET Code Access Security to configure what the control can do when running within the browser.
    [Read This Article]  [Top]
    May 6, 2003 - Building a Simple Mask Control
    James Culshaw shares his experiences building his first working custom control, a basic mask control that allows input of time values, and offers advice and tips to those just starting out.
    [Read This Article]  [Top]
    Mar 3, 2003 - Creating a Server Control for JavaScript Testing
    Learn how to create an ASP.NET server control that detects if a browser supports JavaScript AND if JavaScript is enabled.
    [Read This Article]  [Top]
    Jan 21, 2003 - Protecting Users from Suspect Textual Data
    Learn the ins and outs of composite controls by creating an application that prevents users from submitting offending text.
    [Read This Article]  [Top]
    Aug 27, 2002 - Creating "Self Populating" Controls
    In this article, Luther Stanton shows how to combine inheritance and server controls to create a self-populating drop-down-list control.
    [Read This Article]  [Top]
    Apr 30, 2002 - Building ASP.NET User and Server Controls, Part 2
    Solomon Shaffer explains custom controls, describes the complexities and issues surrounding building such controls, and walks through a useful example.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry



    JupiterOnlineMedia

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info


    Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

    Solutions
    Whitepapers and eBooks
    Microsoft Article: Will Hyper-V Make VMware This Decade's Netscape?
    Microsoft Article: 7.0, Microsoft's Lucky Version?
    Microsoft Article: Hyper-V--The Killer Feature in Windows Server 2008
    Avaya Article: How to Feed Data into the Avaya Event Processor
    Microsoft Article: Install What You Need with Windows Server 2008
    HP eBook: Putting the Green into IT
    Whitepaper: HP Integrated Citrix XenServer for HP ProLiant Servers
    Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 1
    Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 2--The Future of Concurrency
    Avaya Article: Setting Up a SIP A/S Development Environment
    IBM Article: How Cool Is Your Data Center?
    Microsoft Article: Managing Virtual Machines with Microsoft System Center
    HP eBook: Storage Networking , Part 1
    Microsoft Article: Solving Data Center Complexity with Microsoft System Center Configuration Manager 2007
    MORE WHITEPAPERS, EBOOKS, AND ARTICLES
    Webcasts
    Intel Video: Are Multi-core Processors Here to Stay?
    On-Demand Webcast: Five Virtualization Trends to Watch
    HP Video: Page Cost Calculator
    Intel Video: APIs for Parallel Programming
    HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
    Microsoft Silverlight Video: Creating Fading Controls with Expression Design and Expression Blend 2
    MORE WEBCASTS, PODCASTS, AND VIDEOS
    Downloads and eKits
    Sun Download: Solaris 8 Migration Assistant
    Sybase Download: SQL Anywhere Developer Edition
    Red Gate Download: SQL Backup Pro and free DBA Best Practices eBook
    Red Gate Download: SQL Compare Pro 6
    Iron Speed Designer Application Generator
    MORE DOWNLOADS, EKITS, AND FREE TRIALS
    Tutorials and Demos
    How-to-Article: Preparing for Hyper-Threading Technology and Dual Core Technology
    eTouch PDF: Conquering the Tyranny of E-Mail and Word Processors
    IBM Article: Collaborating in the High-Performance Workplace
    HP Demo: StorageWorks EVA4400
    Intel Featured Algorhythm: Intel Threading Building Blocks--The Pipeline Class
    Microsoft How-to Article: Get Going with Silverlight and Windows Live
    MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES