Welcome to GotSpeech.NET Sign in | Join | Help
I remember seing a Microsoft presentation that talked about the three types of deveopers out there, and while it's a pretty broad brush, I think there's some truth to it.  Mort is your reluctant VB developer, who will go into apoplexy if he sees too much code.  Then you have Elvis is your pragmatic C# developer, who isn't afraid of code, but also appreciates the value of tools and .net.  Finally, you have Einstien, who is your "paranoid" C++ developer, who doesn't trust tools, framworks, and often other deveopers.  Obviously, most developers straddle the line between a couple of these, but I know I've met a few Morts and Einstiens in my travels. 

Since Microsoft has already released that MSS 2007 will use Windows Workflow (which is just .net code), there's a good chance that anyone working on a speech application will have to interact with .net code on some level.  True, there are tools that help abstract you from the code, but at some point you might have to dive a little deeper (Especially for those of us who straddle the Elvis/Einstien border).  This brings me around to what I wanted to share in the first place-some thoughts on the new Generics added in .net 2.0.

If you're familiar with .net 1.1, you'll remember that all of the collections (SortedList etc) were of type Object.  This is great, since almost everything in .net derives from Object, but it also seemed to break the trend that .net had with string types and type safety.  I found myself having to cast things all over the place to get collections to work in .net, which made for some messy (and potentially unsafe) code (e.g. ((MyObject)list[i]).MyMethod).  With generics though, it appears that the .net team has done what they should have done the first time (I can only guess that this was a time constraint), and create new, generic collection types. 

For those of us who have used STL, these classes are going to be pretty familiar, except that there aren't as many iterators to worry about.  You're able to create things like List<string> l=new List<string>(), and have a list of strings that's strongly typed.  There's some good documentation in MSDN on how these work (look for the System::Generic namespace), so I won't repeat all of that, but I did want to point out something that might crop up in your application.  Consider this block of code:

            List<string> lStrings=new List<string>();
            lStrings.Add("one");
            lStrings.Add("Two");
            lStrings.Add("Three");
            lStrings.Add("Four");
            lStrings.Add("Five");
            lStrings.Add("Six");

            for (int i = lStrings.Count-1; i >=0; i--)
            {
                string str = lStrings[i] + "forloop";
                if(i%2==0)
                    lStrings.Remove(lStrings[i]);
            }

            foreach (string s in lStrings)
            {
                string str = s + "Loop";
                lStrings.Remove(s);
            }

The first loop takes the list and removes every second string, which works just like you'd expect.  The second loop tries to remove the rest using a foreach loop though (which is another handy .net addition), and throws an exception, saying that the collection has been modified.  In other words-a foreach loop will not work on a generic collection if you modify the collection within the loop.  This operation threw an exception right away though, which means that if you try to do what I did, you'll know right away that it's a problem.

Now, as for the reason I point this out, consider this second example:

            foreach (XmlNode n in node.ChildNodes)
            {
                string s = n.Name;
                if(s=="RemoveMe")
                    node.ChildNodes.Remove(n);
            }


This time, I'm using a foreach loop to iterate through the collection of child XML nodes, and removing all nodes with a particular name.  Sounds simple?  It turns out that this use of foreach has the same problem as the generic implementation, except that this time, instead of throwing an exception, the foreach loop just exits.  This means that if the node n has 2 children named "RemoveMe", the first will be removed by this code, but the second will not be.  As above though, a good old for loop works just fine:

                    for (int i = node.ChildNodes.Count-1; i >= 0; i--)
                    {
                        XmlNode n = node.ChildNodes[i];
                        string s = n.Name;
                        if(s=="RemoveMe")
                            node.ChildNodes.Remove(n);
                    }

So, I suppose the moral of this long winded story-no matter how great the tools are, and how simple things get, sometimes you have to embrace your inner Einstien :)

So today a new video showed up on Channel 9 featuring some of our friends from the Speech Server team talking about MSS 2007.  If this story has dropped from thie front page (as things are wont to do on Channel 9), here's a permalink.  If you've never been to channel 9 before, it's sort of like what you'd get if Microsoft ran slashdot, and there was a lot of video content.  Not a bad site to add an RSS feed for if, like me, you like to keep tabs on what's coming out of Redmond.  Enjoy the video, and a peek at some of the features coming up in MSS 2007. 

On a similar speech related track, has anyone else tried installing the publicly available Vista Beta 2 yet?  Last week, I tossed a second hard drive in my home machine, created a new partition, and loaded up Vista in a dual boot with XP.  Now I'd seen a lot of vista at various Microsoft events and in PDC videos, but this was the first chance I'd had to go hands on with it, and I have to say that it's definitely...different.  The interface is a step above the "Fisher-Price" XP interface, and I've resolved to try using it instead of reverting everything back to "classic", as I have with any of my XP installs.  Other than perhaps being a little too overprotective-evidently, vista really didn't want my to access my "Application Data" directory, since I had to change two separate sets of permissions on my admin account to get at it-it's not a bad looking OS so far. 

The one major complaint I have though is that I can't try out any of the cool speech features in Vista, since my sound card doesn't seem to work correctly.  I have a fairly basic Creative SBLive in the machine, and sound output works just fine, but when I plug a mic into the system, nothing happens.  The same mic works fine in XP (sound recorder works at least), so I'm guessing it's just a vista driver issue.  Microphone input doesn't even show up as a slider in the volume panel, so that's probably indicative of the problem.  This is really too bad, since I was really looking forward to giving this version of desktop speech a try.  If you remember, being able to talk to your computer has been a "feature" of Windows in every new version ever released, so you can understand why a bit of cynicism is natural.  I remember having a lot of fun back in 1997 or so with IBM ViaVoice, and its terrible (and usually hilarious) untrained speech recognition results.  From what I've seen though, both in demos of vista and from the MSS team, the speech rec really has come a long way.  I don't think I'll ever do any serious dictation-having to speak punctuation is still far too cumbersome-but I can see using the speech command interface, especially in a Home Theatre PC scenario with a wireless headset. 

So has anyone tried out speech rec in Vista Beta 2? 

 So here's yet another entry that's not explicitly about speech, but it IS a feature that could be useful in developing on MSS 2007, so I'll post it here anyway.  One of the features that came with Visual Studio 2005 (unfortunately, not supported in C++) was code snippets.  Code snippets are supposed to make development faster and easier by automating the creation of "boilerplate" code, and basically work as an extension of intellisense.  While it might seem at first that these are of dubious usefulness (I know how to complete a for loop thank you very much), creating your own shippets can actually be very useful. 

For example, I had a C# project where I wanted to insert the following block of code into a class:
 string m_S;
 bool m_SCanModify=false;
 public string S{ get { return m_s; } set{ if(m_SCanModify==true) {m_s=value;} } }
 public bool SCanModify{ get{return m_sCanModify;} set {m_sCanModify=value;}}

This code, which contains properties for a private member that can be flagged as read-only, had to be repeated for a large number of members in my application.  Not being able to come up with a way around repeating the code over and over, I originally was going to return to the old "Find+replace" method that I'd used in the past.  Instead I remembered what I'd read about code snippets, and decided to check out what they could do, since I'd heard that in addition to the preloaded code snippets, you could create your own shippets and integrate them into the IDE. 

It turns out that a code snippet is defined in an XML file with a .snippet extension.  Creating one is simply a matter of writing the XML, and then importing it into the IDE by clicking Tools, Code Snippet Manager, and the Import button, and then browsing for the .snippet file.  For the block of code shown above, here's the corresponding snippet file:

 <?xml version="1.0" encoding="utf-8"?>
 <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/CodeSnippet">
   <CodeSnippet Format="1.0.0">
     <Header>
       <Title>Permission Member Snippet</Title>
       <Description>Snippet for member with permission/properties</Description>
       <Author>Chris Bardon</Author>
       <Shortcut>icePermission</Shortcut>
     </Header>
     <Snippet>
       <Declarations>
         <Literal>
           <ID>ObjName</ID>
           <ToolTip>Object to be set</ToolTip>
           <Default>Object name</Default>
         </Literal>
         <Literal>
           <ID>ObjType</ID>
           <ToolTip>Object Type</ToolTip>
           <Default>string</Default>
         </Literal>
         <Literal>
           <ID>Default</ID>
           <ToolTip>Default Value</ToolTip>
           <Default>""</Default>
         </Literal>
       </Declarations>
       <Code Language="CSharp">
         <!--Code Snippet that creates a block with a member variable, a corresponding flag-->
         <!--for readonly access, and the properties to access them-->
         <![CDATA[                           
         $ObjType$ m_$ObjName$=$Default$;
         bool m_$ObjName$CanModify=true;       
         public $ObjType$ $ObjName$ { get { return m_$ObjName$; } set { if (m_$ObjName$CanModify == true) { m_$ObjName$ = value; } } }
         public bool $ObjName$CanModify { get { return m_$ObjName$CanModify; } set { m_$ObjName$CanModify = value; } }
                 ]]>
       </Code>
     </Snippet>
   </CodeSnippet>
 </CodeSnippets>

Of course, some of this XML merits explanation.  The header contains some basic fields describing the snippet that show up in the snippet manager, as well as a <shortcut> element.  This element is important, as it contains the string you can type into the editor to insert the snippet.  The string will show up in the intellisense dropdown, and you can complete it by hitting TAB twice.  Once imported, you can also right click in the IDE and select "insert snippet", or choose "insert snippet" from the tools menu, but those both require using a mouse, and if you're writing code, your hands are already on the keyboard.  This is why shortcuts are useful.  This snippet also contains a declarrations section, which defines substitution text for the snippet, and represented by wrapping the ID in $ characters in the code.  When the snippet is inserted, the fields to be modified are highlighted in green, and you can TAB between them.  The IDE will also change ALL occurrances of a field once the first one is set, so in my case, defining $ObjType$ as string will change both instances.  The documentation in MSDN for code snippets is actually pretty good, and there's a good section to explain what the XML schema for the snippet file is.

I should also note that this is really a first attempt at using Code Snippets, and I've probably broken a few design rules in the process, but I think it's a decent first stab at things.  Want to take a shot at using code snippets without writing your own?  The next time you're writing C#, when you type "for", and see it show up in the intellisense dropdown, hit TAB twice, and see what happens.

Aha, something that's not specific to MSS 2007-SIP debugging.  A lot of people spend a lot of time trying to work with SIP devices on various platforms, one of which might just happen to be the MSS 2007 beta.  Regardless of the server though, debugging SIP can be a huge headache.  Some platforms are kind enough to log SIP messages for you, but too often these are just flat file text logs that are very difficult to wade through to find what you're looking for.

Enter Ethereal (http://www.ethereal.com/).

Ethereal is one of the greatest open source tools ever created.  First off, it's free. This sets it apart from a lot of other network tools in that your IT/purchasing department will probably not hassle you about installing it.  Second, once you install Ethereal, you can monitor traffic on any network card and using any protocol your machine cares to use.  This traffic is viewable as either raw hex data (for those of you who like getting "close to the hardware") or as parsed, protocol specific information.  Filters are already in place for all of the major protocols (including SIP), which means that all of your SIP header information is on the screen and easy to access. 

I'm not going to reproduce the product docs here, since the ethereal website does a pretty good job, and the app is reasonably straightforward.  I will point out a few things though:

  • Checking off the display options "update list of packets in real time", "Automatic scrolling in Live Capture", and "hide capture info dialog" on a new session makes things much easier to work with.
  • Performance is much better if you can filter by either address (e.g. host 192.168.200.1) or port (e.g. port 5060) in the capture options rather than the display.
  • You can also filter display results (including incoming, live results) in the capture window.  This is useful for, say, capturing all SIP traffic on a server, and then filtering to see traffic coming from a particular endpoint.
  • You can also filter by protocol in the capture window, so you can set up to capture all traffic, then type SIP in the filter dialog to see all SIP traffic. 
  • For SIP calls, you can even go as far as to decode RTP traffic and play it back as audio.  If this isn't motivation for SRTP, I don't know what is...

The only downside is that since Ethereal sits at the protocol level, it can't decrypt messages that are encrypted by the application.  For SIP, this means that if your signalling is running over MTLS, then you're out of luck for diagnosing SIP problems with Ethereal. 

There are literally dozens of these little tricks and hints for Ethereal that make the application very powerful, and new features are always being added to the application.  If anyone has any they'd like to share, list em in the comments, or start a thread on gotspeech.net to talk about em.

So this is all Brandon Tyler's fault. 

Just thought I'd get that out of the way at the beginning.  I know Brandon through our participation in a secret Microsoft program that we're not supposed to discuss, and he suggested that the gotspeech.net community might "benefit from my input".  By "benefit from my input" I assume he meant something closer to "post your findings/thoughts/rants on speech server", so I gladly accepted.  Here's the problem though-I've barely ever used MSS 2004.  I've got a lot of experience with MSS 2007, speech, IVR, Contact Center, .net, C++, and a bunch of other stuff, but only got into MSS with 2007 back in October.  I'd tried MSS 2004 once before that, and found the whole SALT thing to be cumbersome, and generally unpleasant.  I can confidently say without hyperbole that the new way of doing things in 2007 is a million times better. 

So, this blog presents a bit of a challenge.  The NDA all of us beta people have with Microsoft says that we can't talk about anything in the new version, so I'm going to try to post things without actually breaking that NDA.  I have a severe allergy to getting sued you see...  What can I talk about?  That's a good question...

As for me, what's there to say.  I've been with ComputerTalk (http://www.computer-talk.com) for about 3 years now, working in Research & Development on our icecube contact center platform.  I've got both a Bachelor's and a Master's degree in Systems Design Engineering from the University of Waterloo, and I've been writing software since the days of C64 BASIC (sadly, I still remember POKE 54261,1 changed the screen colour).  I work primarily in C# and C++, on both speech applications and regular client/server/desktop/web stuff.  I also have an Xbox360 (gamertag ChrisBardon). 

More to come...