Contents tagged with Speech Server 2007
-
OCS: New Version, New Name
The press releases went up a few minutes ago so I can finally share this.
The overly long winded name Microsoft Office Communications Server is no more. The entire product line (including Office Communicator) has been rebranded as “Lync”.
The new product line will include:
- Lync 2010 (replaces Communicator)
- Lync Server 2010 (replaces Office Communications Server)
- Lync Online (replaces Communications Online)
- Lync Web App (replaces Web Communicator)
You can read the full press release here: http://www.microsoft.com/Presspass/press/2010/sep10/LyncPR.mspx
UPDATE: The UC Team has released some more details on their blog http://blogs.technet.com/b/uc/archive/2010/09/13/introducing-microsoft-lync-the-next-ocs.aspx
-
SIP Monitoring with Wireshark
Wireshark is a free tool for capturing network traffic. It is an invaluable resource for troubleshooting problems with VOIP calls. It is available for download from www.wireshark.org (current version for Windows as of this post is 1.05)....
-
Fixing the Red-X on x64
A while ago Microsoft released a patch for the nasty red X that would appear over certain workflow activities (KB950210). Unfortunately this patch only worked on 32 bit editions of Windows. If you were running Vista x64 for example the patch would fail during installation....
-
Common Outbound Issues
More developers are starting to work with Office Communication Server 2007 these days. As the community has grown I’ve noticed a number of developers running into a few “gotchas” when working with the OCS outbound calling mechanism. ...
-
Office Communication Servers moves to 64-bit only
The Office Communication Server team announced Friday that OCS 2007 R2 will support 64-bit operating systems only.
As a part of the broad initiative across Microsoft to support 64 bit versions across many of its product lines, the next release of OCS will support 64-bit operating systems only. This decision will help meet customer demand and is a natural progression of the product that aligns with the same approach taken by the Exchange team (with Exchange 2007) and the SharePoint team (with SharePoint 2007) to support 64 bit operating systems only....
-
Building Custom Activities Using the Core API
The Speech Server API is interesting to play around with. And understanding how Speech Server works behind the scenes is invaluable in debugging. But the real value of learning the API comes when you decide to build your own custom activities....
-
Getting Started with the Core API
With the introduction of Voice Response Workflows in Speech Server 2007, Microsoft has greatly simplified voice-enabled application development. The entire process is relatively painless; even downright enjoyable. And for most applications it is all you'll need to build outstanding applications. ...
-
New Blog: Speaking From the Edge
I've started a new blog over on GotSpeech.net called Speaking From the Edge. It covers topics related to voice-enabled application development including Microsoft Speech Server.
I'm not abandoning this site however. I will continue to post here as well. I'm also putting some thought to re-launching this blog to focus on other topics I'm interested in.
-
Executing a Speech Server Workflow via the API
In my previous post I outlined a basic framework for using the Core API for Speech Server 2007. Today I'll outline how to mix both the API and Workflow models by calling out to a workflow using the API and returning control back when it is complete.
If you are interested in the complete project code you may download it here.
I'm starting with the same basic framework from my last post. To this I'm adding a simple Voice Response Workflow with a single Statement activity. Rather than calling the synthesizer from the API, I'm going to use the Statement activity inside the workflow. We're going to pass in the text we want it to play at runtime.
1) The first thing we need to do is add a new Voice Response Workflow to the project. Too this we'll add a single Statement activity. Because we've established the call using the API there is no AnswerCall, MakeCall, or DisconnectCall activities in this workflow.
2) Now that we have our really-big-and-complex workflow ready, we can start adding some code to set the prompt. The first thing we need to do is add a handler for the TurnStarting event. This is where we will assign the Main Prompt property for the activity.
3) Next we need to add a property to pass in our input parameters too. We'll call this MyPrompt. The resulting code behind should look like the following:
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SpeechServer.Dialog;namespace VoiceResponseWorkflowApplication2
{
public sealed partial class Workflow1: SpeechSequentialWorkflowActivity
{
public Workflow1()
{
InitializeComponent();
}private string _myPrompt;
public string MyPrompt
{
get { return _myPrompt; }
set { _myPrompt = value; }
}private void statementActivity1_TurnStarting(object sender, TurnStartingEventArgs e)
{
statementActivity1.MainPrompt.SetText(MyPrompt);
}
}
}4) Now we need to add some code to kick off the workflow. We'll do this from within the OpenCompleted event handler in Class1.cs. This code establishes an input parameter Dictionary<>, instantiates the workflow object, and starts the workflow. We'll add a handler for the WorkflowCompleted event so that we can cleanup the call once the workflow is done.
Dictionary<string, object> inputParam = new Dictionary<string, object>();
inputParam.Add("MyPrompt", "HelloWorld");
myWorkflow = SpeechSequentialWorkflowActivity.CreateWorkflow(_host, typeof(Workflow1), inputParam);
myWorkflow.WorkflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(WorkflowRuntime_WorkflowCompleted);
SpeechSequentialWorkflowActivity.Start(myWorkflow);One interesting item here is the inputParam object. The way this works is that you pass in parameters to the workflow and it assigns the values to the corresponding public properties of the workflow. If you pass an input parameter for which there is no property you will get an exception.
The complete Class1.cs:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SpeechServer ;
using Microsoft.SpeechServer.Dialog;
using System.Workflow.Runtime;namespace VoiceResponseWorkflowApplication2
{
public class Class1 : IHostedSpeechApplication
{
private IApplicationHost _host;
private WorkflowInstance myWorkflow;public void Start(IApplicationHost host)
{
if (host != null)
{
_host = host;
_host.TelephonySession.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");// Dial and outbound call (make sure you change these numbers :-)
_host.TelephonySession.OpenCompleted += new EventHandler<AsyncCompletedEventArgs>(TelephonySession_OpenCompleted);
_host.TelephonySession.OpenAsync("7813062200", "8887006263");
}
else
{
throw new ArgumentNullException("host");
}
}void TelephonySession_OpenCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
_host.TelephonySession.Close();
}
else
{
Dictionary<string, object> inputParam = new Dictionary<string, object>();
inputParam.Add("MyPrompt", "HelloWorld");
myWorkflow = SpeechSequentialWorkflowActivity.CreateWorkflow(_host, typeof(Workflow1), inputParam);
myWorkflow.WorkflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(WorkflowRuntime_WorkflowCompleted);
SpeechSequentialWorkflowActivity.Start(myWorkflow);
}
}void WorkflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
{
_host.TelephonySession.Close();
}public void Stop(bool immediate)
{}
public void OnUnhandledException(Exception exception)
{
if (exception != null)
{
_host.TelephonySession.LoggingManager.LogApplicationError(100, "An unexpected exception occurred: {0}", exception.Message);
}
else
{
_host.TelephonySession.LoggingManager.LogApplicationError(100, "An unknown exception occurred: {0}", System.Environment.StackTrace);
}_host.OnCompleted();
}
}
} -
Getting Started with the Speech Server 2007 API
Speech Server 2007 has a really cool Windows Workflow based programming model that lets you quickly build interactive voice response applications. For many applications it is all you will ever need.
Sometimes however you find the workflow model just isn't the right fit. If you're looking for really fine-grained control over the application, or you simply prefer to work in code, then the Core API is what you need.
Unfortunately figuring out you want to use the API is a lot easier than figuring out how to start using it. There is very little documentation and no Visual Studio project templates or samples included with Speech Server.
I'll do my best to give a brick-simple explanation of how to get your first core API project started. You can also download the zipped project files.
1) First you'll need to create a new Voice Response Workflow Application. We'll use the project that gets generated as our foundation.
2) When asked for the application resources you'll want to uncheck everything.
3) Open up the Class1.cs file and remove all of the references to the VoiceResponseWorkflow1 class. The resulting class should look like the following (I removed the comments in the code for brevity):
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SpeechServer ;
using Microsoft.SpeechServer.Dialog;namespace VoiceResponseWorkflowApplication1
{
public class Class1 : IHostedSpeechApplication
{
private IApplicationHost _host;public void Start(IApplicationHost host)
{
if (host != null)
{
_host = host;
_host.TelephonySession.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
}
else
{
throw new ArgumentNullException("host");
}
}
public void Stop(bool immediate)
{
}public void OnUnhandledException(Exception exception)
{
if (exception != null)
{
_host.TelephonySession.LoggingManager.LogApplicationError(100, "An unexpected exception occurred: {0}", exception.Message);
}
else
{
_host.TelephonySession.LoggingManager.LogApplicationError(100, "An unknown exception occurred: {0}", System.Environment.StackTrace);
}_host.OnCompleted();
}
}
}That's all folks. Class1.cs is now the starting point of your Core API application. As a further example, lets take the project and add some code to turn it into an outbound dialing "Hello World" application.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SpeechServer ;
using Microsoft.SpeechServer.Dialog;namespace VoiceResponseWorkflowApplication1
{
public class Class1 : IHostedSpeechApplication
{
private IApplicationHost _host;public void Start(IApplicationHost host)
{
if (host != null)
{
_host = host;
_host.TelephonySession.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
// Dial and outbound call (make sure you change these numbers :-)
_host.TelephonySession.OpenCompleted += new EventHandler<AsyncCompletedEventArgs>(TelephonySession_OpenCompleted);
_host.TelephonySession.OpenAsync("7813062200", "8887006263");
}
else
{
throw new ArgumentNullException("host");
}
}void TelephonySession_OpenCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
_host.TelephonySession.Close();
}
else
{
_host.TelephonySession.Synthesizer.SpeakCompleted += new EventHandler<Microsoft.SpeechServer.Synthesis.SpeakCompletedEventArgs>(Synthesizer_SpeakCompleted);
_host.TelephonySession.Synthesizer.SpeakAsync("Hello World", Microsoft.SpeechServer.Synthesis.SynthesisTextFormat.PlainText);
}
}void Synthesizer_SpeakCompleted(object sender, Microsoft.SpeechServer.Synthesis.SpeakCompletedEventArgs e)
{
_host.TelephonySession.Close();
}
public void Stop(bool immediate)
{
}public void OnUnhandledException(Exception exception)
{
if (exception != null)
{
_host.TelephonySession.LoggingManager.LogApplicationError(100, "An unexpected exception occurred: {0}", exception.Message);
}
else
{
_host.TelephonySession.LoggingManager.LogApplicationError(100, "An unknown exception occurred: {0}", System.Environment.StackTrace);
}_host.OnCompleted();
}
}
}