Windows Phone SDK 8.0 新特性-Speech
1. 引言
随着Windows Phone SDK 8.0的发布,其包含的新特性也受到了广大开发者的关注,其中之一就是语音方面的提升。其实在Windows Phone SDK 8.0发布之前,Kinect for Windows也更新了其SDK,支持了其他新的语言,可惜没有看到支持中文的选项。而Windows Phone SDK 8.0的Speech中包含了中文的支持,这点令我们中文用户感受到了MS对中国市场的重视。这点大家可以在Windows Phone 8 模拟器中看到,将模拟器的语言设置为中文,进入设置-语音-语音语言,看到其支持的语言如下图1所示。除了普通话,Windows Phone 8还支持粤语和台湾语的语音识别。
图1:Windows Phone 8 Speech支持的语言种类
2. 与App交互的三个Speech组件
在Windows Phone 8 中,用户可以通过三种方式与App进行语音的交互。
- Voice Commands
- Speech Recognition
- Text-to-speech (TTS)
其交互方式如下图2所示。
图2:用户与应用程序进行语音交互的三种方式
2.1 Voice Commands
该功能其实在Windows Phone 7.5中就已经包含了,但那只是简单的诸如“启动某个应用程序”、“打电话给某人”等语音指令。但是在Windows Phone 8 中,该语音指令又得到了进一步的提升。用户可以通过语音,在启动应用程序时,进行深层次的操作。比如,“打开某应用程序,显示某页面”,“打开某应用程序,查询今日天气”等等。
另外,语音指令的提示对于用户来说也是很重要的一环,用户可以通过“我该说什么”页面来发掘应用程序的语音指令,如下图3所示。
图3:“我该说什么”页面的“应用程序”界面
“我该说什么”页面是一个典型的Pivot页面,主要包含了“常用”、“应用程序”和“更多”这三个选项。在“应用程序”页面中,如果系统安装了语音指令的应用程序,那么,该页面就会显示一些语音指令的提示。例如,我在模拟器中安装了“智能语音”程序,在该页面中显示了“智能语音,请说:打开 智能语音”这条提示。通过后面的程序编写,开发者可以对该提示进行设置。
有关Windows Phone 8 中Voice Commands的进一步详细资料,可以参考MSDN上的文档:Voice commands for Windows Phone 8。
2.2 Speech Recognition
在应用程序中,通过Speech Recognition功能,用户可以使用语音来进行输入,或者是完成某个任务。Speech Recognition与Voice Commands的最大区别就在于使用场合:Speech Recognition用于应用程序内部,而Voice Commands是在应用程序外部。对于文本输入和网页搜索,Windows Phone 8包含了对预定义语法的支持;对于用户自定义的语法,必须遵循工业级的《Speech Recognition Grammar Specification (SRGS) Version 1.0》规范。有关语音识别的具体内容,可以参考MSDN的文档:Text-to-speech (TTS) for Windows Phone。
2.3 Text-to-Speech(TTS)
在应用程序内部,开发者可以使用Text-to-Speech(TTS),或者说是语音合成技术,将文本内容通过Microphone读给用户听。同样,文本的内容可以是字符串,也可以是一句话,其遵循的规范是《Speech Synthesis Markup Language (SSML) Version 1.0》。具体信息可以参考MSDN的文档:Text-to-speech (TTS) for Windows Phone。
3. Voice Commands示例
通过该示例,我们实现的功能包括打开应用程序和打开应用程序的某个页面。
首先,我们打开Visual Studio,新建工程,命名为VoiceAppDemo。为了使应用程序具备语音识别的能力,我们在WMAppManifest.xml文件中,加入MicroPhone和Speech Recognition的Capability选项,如下图4所示。
图4:WMAppManifest.xml文件中加入语音识别的选项
为了体现Windows Phone 8对中文语音的支持,我们在WMAppManifest.xml的Application UI中,将Display Name设置为“智能语音”,如下图5所示。
图5:WMAppManifest.xml文件中将应用程序设置为中文名称
之后,在项目中,通过右键加入新文件,选择Voice Command Defination,命名为SupportedVoiceCommands.xml,如下图6所示。
图6:新加入语音指令定义文件
修改其语音指令定义文件,内容如下:
1: <?xml version="1.0" encoding="utf-8"?>
2: <VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.0">
3: <CommandSet xml:lang="zh-cn">
4: <CommandPrefix> 智能语音 </CommandPrefix>
5: <Example> 请说:打开 智能语音</Example>
6: </CommandSet>
7: </VoiceCommands>
该语音指令文件在程序第一次运行时,需要进行注册,我们可以在App.xaml.cs文件中,加入对该语音指令文件的注册,函数命名为InitializeVoiceCommands,其实现代码如下:
1: async private static void InitializeVoiceCommands()
2: {
3: var filename = "SupportedVoiceCommands.xml";
4:
5: try
6: {
7: var location = Windows.ApplicationModel.Package.Current.InstalledLocation.Path;
8: var fileUriString = String.Format("file://{0}/{1}", location, filename);
9: await Windows.Phone.Speech.VoiceCommands.VoiceCommandService.InstallCommandSetsFromFileAsync(new Uri(fileUriString));
10: }
11: catch (Exception ex)
12: {
13: System.Diagnostics.Debug.WriteLine(ex.Message);
14: }
15: }
同时,在App()构造函数中加入InitializeVoiceCommands()。其代码如下:
1: public App()
2: {
3: // Global handler for uncaught exceptions.
4: UnhandledException += Application_UnhandledException;
5:
6: // Standard XAML initialization
7: InitializeComponent();
8:
9: // Phone-specific initialization
10: InitializePhoneApplication();
11:
12: // Language display initialization
13: InitializeLanguage();
14:
15: InitializeVoiceCommands();
16:
17: // Show graphics profiling information while debugging.
18: if (Debugger.IsAttached)
19: {
20: // Display the current frame rate counters.
21: Application.Current.Host.Settings.EnableFrameRateCounter = true;
22:
23: // Show the areas of the app that are being redrawn in each frame.
24: //Application.Current.Host.Settings.EnableRedrawRegions = true;
25:
26: // Enable non-production analysis visualization mode,
27: // which shows areas of a page that are handed off to GPU with a colored overlay.
28: //Application.Current.Host.Settings.EnableCacheVisualization = true;
29:
30: // Prevent the screen from turning off while under the debugger by disabling
31: // the application's idle detection.
32: // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
33: // and consume battery power when the user is not using the phone.
34: PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
35: }
36:
37: }
此时,我们就可以进行语音指令的测试了。选择对应的模拟器类型,点击Degub,使得应用程序部署到模拟器,并且开始运行。在第一次运行的时候,应用程序通过InstallCommandSetsFromFileAsync进行了语音指令的注册。之后,我们可以点击退出,回到Start界面。长按Windows按钮,系统跳出语音界面,对着Microphone说:“打开智能语音”。系统会弹出提示信息,显示正在打开智能语音。
进行到这里,我们只实现了通过语音指令打开应用程序,并且显示应用程序主页面的目的。但是,对于用户具体的需求,开发者可以在SupportedVoiceCommands.xml文件中进行更多更细致的定义。例如,我的应用程序包含了Panorama页面和Pivot页面,在应用程序启动的时候,我想显示其中的一个页面。那么,首先,我们可以在项目中添加两个新页面,命名为PanoramaPage.xaml和PivotPage.xaml。如下图7所示。
图7:添加新页面
然后,在SupportedVoiceCommands.xml文件中,扩充对语音指令的定义,假设用户在应用程序启动的时候,新增了打开PanoramaPage和PivotPage的需求。那么我们可以将其语音指令的定义扩充如下:
1: <?xml version="1.0" encoding="utf-8"?>
2: <VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.0">
3: <CommandSet xml:lang="zh-cn">
4:
5: <CommandPrefix> 智能语音 </CommandPrefix>
6: <Example> 请说:打开 智能语音</Example>
7:
8: <Command Name="测试全景页面">
9: <Example>跳到全景页面</Example>
10: <ListenFor>跳到全景页面</ListenFor>
11: <Feedback>正在打开智能语音 显示全景页面</Feedback>
12: <Navigate Target="PanoramaPage.xaml"></Navigate>
13: </Command>
14:
15: <Command Name="测试枢轴页面">
16: <Example>跳到枢轴页面</Example>
17: <ListenFor>跳到枢轴页面</ListenFor>
18: <Feedback>正在打开智能语音 显示枢轴页面</Feedback>
19: <Navigate Target="PivotPage.xaml"></Navigate>
20: </Command>
21:
22: </CommandSet>
23: </VoiceCommands>
在以上的语英指令Command中,ListenFor代表应用程序监听的内容,Feedback代表信息提示显示的内容,Navigate代表页面导航的具体参数。在这里,我们直接将Target设置为对应的全景页面或者是对应的枢轴页面。
重新编译,然后调试。在应用程序运行以后,点击退出,回到Start页面。接着长按Windows按钮,在弹出语音输入提示后,对着Microphone说:“打开智能语音,跳到全景页面”,或者“打开智能语音,跳到枢轴页面”,系统会弹出提示信息,显示正在打开智能语音,跳到对应的页面。如下图8所示。这样就实现了打开应用程序,并且直接进入应用程序的某个页面的目的。
图8: 通过语音指令直接打开应用程序的枢轴页面和全景页面
4.结语
本文介绍了Windows Phone 8 SDK中的Speech特性,并且针对Voice Commands,给出了示例。