重新想象 Windows 8.1 Store Apps (87) - TTS: Speak Text, Speak SSML-程序员宅基地

技术标签: ui  人工智能  

原文: 重新想象 Windows 8.1 Store Apps (87) - TTS: Speak Text, Speak SSML

[源码下载]


重新想象 Windows 8.1 Store Apps (87) - TTS: Speak Text, Speak SSML



作者:webabcd


介绍
重新想象 Windows 8.1 Store Apps 之 TTS(Text To Speech)

  • Speak Text
  • Speak SSML



示例
1、演示如何通过 TTS 朗读一段文本,以及如何将其保存为音频文件
SpeakText.xaml

<Page
    x:Class="Windows81.TTS.SpeakText"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.TTS"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <!--用于播放音频-->
            <MediaElement Name="mediaElement" AutoPlay="False" />

            <TextBlock Name="lblMsg" FontSize="14.667" Margin="0 10 0 0" />
            
            <!--需要被 TTS 的文本-->
            <TextBlock Name="lblText" FontSize="14.667" Margin="0 10 0 0" Text="TTS 是 Text To Speech 的缩写,即“从文本到语音”,是人机对话的一部分,让机器能够说话。" />
            
            <!--开始 TTS-->
            <Button Name="btnSpeakText" Content="Speek Text" Click="btnSpeakText_Click" Margin="0 10 0 0" />

            <!--保存 TTS 转换出的音频文件-->
            <Button Name="btnSaveAudio" Content="Save Audio" Click="btnSaveAudio_Click" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
</Page>

SpeakText.xaml.cs

/*
 * 演示如何通过 TTS 朗读一段文本,以及如何将其保存为音频文件
 * 
 * 注:Windows Phone 中的“TTS, 语音识别, 语音命令”请参见:http://www.cnblogs.com/webabcd/archive/2014/01/02/3501356.html
 */

using System;
using System.Collections.Generic;
using Windows.Media.SpeechSynthesis;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace Windows81.TTS
{
    public sealed partial class SpeakText : Page
    {
        // TTS 引擎
        private SpeechSynthesizer _synthesizer = new SpeechSynthesizer();

        public SpeakText()
        {
            this.InitializeComponent();

            lblMsg.Text = "系统支持的语音有:";
            // TTS 引擎所支持的全部语音信息
            var voices = SpeechSynthesizer.AllVoices;
            foreach (VoiceInformation voice in voices)
            {
                lblMsg.Text += voice.DisplayName + ", ";
            }

            lblMsg.Text += Environment.NewLine;
            // 获取或设置当前 TTS 引擎所使用的语音
            lblMsg.Text += "当前 TTS 使用的语音是:" + _synthesizer.Voice.DisplayName;

            // SpeechSynthesizer 实现了 IDisposable 接口
            // _synthesizer.Dispose();

            this.mediaElement.CurrentStateChanged += mediaElement_CurrentStateChanged; 
        }

        void mediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
        {
            if (mediaElement.CurrentState == MediaElementState.Paused)
            {
                btnSpeakText.IsEnabled = true;
            }
        }

        // 播放 TTS 音频
        private async void btnSpeakText_Click(object sender, RoutedEventArgs e)
        {
            // TTS 引擎生成的音频流
            SpeechSynthesisStream synthesisStream;

            try
            {
                // 通过 TTS 引擎将字符串转换成音频流
                synthesisStream = await _synthesizer.SynthesizeTextToStreamAsync(lblText.Text);
            }
            catch (Exception ex)
            {
                lblMsg.Text = ex.ToString();

                synthesisStream = null;
                btnSpeakText.IsEnabled = true;
            }

            // 播放音频流
            mediaElement.AutoPlay = true;
            mediaElement.SetSource(synthesisStream, synthesisStream.ContentType);
            mediaElement.Play();
        }

        // 保存 TTS 音频
        private async void btnSaveAudio_Click(object sender, RoutedEventArgs e)
        {
            FileSavePicker savePicker = new FileSavePicker();
            savePicker.DefaultFileExtension = ".wav";
            savePicker.FileTypeChoices.Add("Audio file", new List<string>() { ".wav" });

            StorageFile file = await savePicker.PickSaveFileAsync();
            if (file != null)
            {
                btnSaveAudio.IsEnabled = false;

                SpeechSynthesisStream synthesisStream;
                try
                {
                    synthesisStream = await _synthesizer.SynthesizeTextToStreamAsync(lblText.Text);
                }
                catch (Exception ex)
                {
                    lblMsg.Text = ex.ToString();

                    synthesisStream = null;
                    btnSaveAudio.IsEnabled = true;
                }

                // 保存音频数据到文件
                Windows.Storage.Streams.Buffer buffer = new Windows.Storage.Streams.Buffer(4096);
                IRandomAccessStream writeStream = (IRandomAccessStream)await file.OpenAsync(FileAccessMode.ReadWrite);
                IOutputStream outputStream = writeStream.GetOutputStreamAt(0);
                DataWriter dataWriter = new DataWriter(outputStream);
            
                while (synthesisStream.Position < synthesisStream.Size)
                {
                    await synthesisStream.ReadAsync(buffer, 4096, InputStreamOptions.None);
                    dataWriter.WriteBuffer(buffer);
                }

                dataWriter.StoreAsync().AsTask().Wait();
                outputStream.FlushAsync().AsTask().Wait();

                btnSaveAudio.IsEnabled = true;
            }
        }
    }
}


2、演示如何通过 TTS 朗读 SSML 协议文档,以及如何将其保存为音频文件
SpeakSSML.xaml

<Page
    x:Class="Windows81.TTS.SpeakSSML"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.TTS"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <!--用于播放音频-->
            <MediaElement Name="mediaElement" AutoPlay="False" />

            <TextBlock Name="lblMsg" FontSize="14.667" Margin="0 10 0 0" />

            <!--开始 TTS-->
            <Button Name="btnSpeakSSML" Content="Speek SSML" Click="btnSpeakSSML_Click" Margin="0 10 0 0" />

            <!--保存 TTS 转换出的音频文件-->
            <Button Name="btnSaveAudio" Content="Save Audio" Click="btnSaveAudio_Click" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
</Page>

SpeakSSML.xaml.cs

/*
 * 演示如何通过 TTS 朗读 SSML 协议文档,以及如何将其保存为音频文件
 * 
 * 注:Windows Phone 中的“TTS, 语音识别, 语音命令”请参见:http://www.cnblogs.com/webabcd/archive/2014/01/02/3501356.html
 * 
 * 
 * 另外:
 * 1、SSML - Speech Synthesis Markup Language
 * 2、微软关于 ssml 的说明:http://msdn.microsoft.com/en-us/library/hh361578
 * 3、W3C 关于 ssml 的说明:http://www.w3.org/TR/speech-synthesis/
 */

using System;
using System.Collections.Generic;
using Windows.Media.SpeechSynthesis;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace Windows81.TTS
{
    public sealed partial class SpeakSSML : Page
    {
        // TTS 引擎
        private SpeechSynthesizer _synthesizer = new SpeechSynthesizer();

        public SpeakSSML()
        {
            this.InitializeComponent();
            
            lblMsg.Text = "系统支持的语音有:";
            // TTS 引擎所支持的全部语音信息
            var voices = SpeechSynthesizer.AllVoices;
            foreach (VoiceInformation voice in voices)
            {
                lblMsg.Text += voice.DisplayName + ", ";
            }

            lblMsg.Text += Environment.NewLine;
            // 获取或设置当前 TTS 引擎所使用的语音
            lblMsg.Text += "当前 TTS 使用的语音是:" + _synthesizer.Voice.DisplayName;

            // SpeechSynthesizer 实现了 IDisposable 接口
            // _synthesizer.Dispose();

            this.mediaElement.CurrentStateChanged += mediaElement_CurrentStateChanged;
        }

        void mediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
        {
            if (mediaElement.CurrentState == MediaElementState.Paused)
            {
                btnSpeakSSML.IsEnabled = true;
            }
        }

        // 播放 TTS 音频(SSML)
        private async void btnSpeakSSML_Click(object sender, RoutedEventArgs e)
        {
            // TTS 引擎生成的音频流
            SpeechSynthesisStream synthesisStream;

            try
            {
                // 构造一个 SSML 协议文档
                string ssml = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"zh-CN\">"; // 中文
                ssml += "<voice gender=\"male\">"; // 男声
                ssml += "<prosody rate=\"-50%\">"; // 语速放慢 50%
                ssml += "TTS 是 Text To Speech 的缩写,即“从文本到语音”,是人机对话的一部分,让机器能够说话。";
                ssml += "</prosody>";
                ssml += "</voice>";
                ssml += "</speak>";

                // 通过 TTS 引擎将 SSML 协议文档转换成音频流
                synthesisStream = await _synthesizer.SynthesizeSsmlToStreamAsync(ssml);
            }
            catch (Exception ex)
            {
                lblMsg.Text = ex.ToString();

                synthesisStream = null;
                btnSpeakSSML.IsEnabled = true;
            }

            // 播放音频流
            mediaElement.AutoPlay = true;
            mediaElement.SetSource(synthesisStream, synthesisStream.ContentType);
            mediaElement.Play();
        }

        // 保存 TTS 音频(SSML)
        private async void btnSaveAudio_Click(object sender, RoutedEventArgs e)
        {
            FileSavePicker savePicker = new FileSavePicker();
            savePicker.DefaultFileExtension = ".wav";
            savePicker.FileTypeChoices.Add("Audio file", new List<string>() { ".wav" });

            StorageFile file = await savePicker.PickSaveFileAsync();
            if (file != null)
            {
                btnSaveAudio.IsEnabled = false;

                SpeechSynthesisStream synthesisStream;
                try
                {
                    // 构造一个 SSML 协议文档
                    string ssml = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"zh-CN\">"; // 中文
                    ssml += "<voice gender=\"male\">"; // 男声
                    ssml += "<prosody rate=\"-50%\">"; // 语速放慢 50%
                    ssml += "TTS 是 Text To Speech 的缩写,即“从文本到语音”,是人机对话的一部分,让机器能够说话。";
                    ssml += "</prosody>";
                    ssml += "</voice>";
                    ssml += "</speak>";

                    // 通过 TTS 引擎将 SSML 协议文档转换成音频流
                    synthesisStream = await _synthesizer.SynthesizeSsmlToStreamAsync(ssml);
                }
                catch (Exception ex)
                {
                    lblMsg.Text = ex.ToString();

                    synthesisStream = null;
                    btnSaveAudio.IsEnabled = true;
                }

                // 保存音频数据到文件
                Windows.Storage.Streams.Buffer buffer = new Windows.Storage.Streams.Buffer(4096);
                IRandomAccessStream writeStream = (IRandomAccessStream)await file.OpenAsync(FileAccessMode.ReadWrite);
                IOutputStream outputStream = writeStream.GetOutputStreamAt(0);
                DataWriter dataWriter = new DataWriter(outputStream);

                while (synthesisStream.Position < synthesisStream.Size)
                {
                    await synthesisStream.ReadAsync(buffer, 4096, InputStreamOptions.None);
                    dataWriter.WriteBuffer(buffer);
                }

                dataWriter.StoreAsync().AsTask().Wait();
                outputStream.FlushAsync().AsTask().Wait();

                btnSaveAudio.IsEnabled = true;
            }
        }
    }
}



OK
[源码下载]

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34364135/article/details/85658002

智能推荐

HttpClient 带参数get请求_httpclient get 参数-程序员宅基地

文章浏览阅读1.1w次。1.参数:filename:服务器上存储文件的文件名2.返回值输入流,以流的形式返回,不需要保存在本地浪费资源,使用时调用方法传参拿到返回值就可以使用实例public static InputStream doGet(String filename) { //创建HttpClient实例 CloseableHttpClient httpClient = HttpClient..._httpclient get 参数

centOS yum 安装mysql-程序员宅基地

文章浏览阅读373次。安装MySQL。[root@sample ~]# yum -y install mysql-server  ← 安装MySQL[root@sample ~]# yum -y install php-mysql  ← 安装php-mysql配置MySQL[root@sample ~]#vim /etc/my.cnf  ← 编辑MySQL的配置文件[mysqld]datadir

[3]数值计算与基于梯度的优化算法-程序员宅基地

文章浏览阅读514次。文章目录1 数值计算1.1 上溢和下溢以及softmax函数1.2 病态条件2 基于梯度的优化方法2.1 基本概念2.2 梯度下降2.3 Jacobian和Hessian矩阵2.3.1 Hessian矩阵的性质2.3.2 步长优化2.3.3 牛顿法(Newton's Method)优化2.4 约束优化2.5 (实例)线性最小二乘1 数值计算1.1 上溢和下溢以及softmax函数计算机在存储连续数学信息的时候,只能通过有限位数来近似逼近我们期望的“无限长度”的数字。下溢指的是当数据过小导致计算机近似

如何为英伟达TX2编译内核和设备树_tx2 内核编译-程序员宅基地

文章浏览阅读8.7k次,点赞5次,收藏35次。在编译内核和设备树之前,首先默认已经安装了JetPack,如果没有安装,请参考其它资料进行安装。1、首先需要下载编译内核需要用到的工具链,通过下面的链接下载。https://developer.nvidia.com/embedded/dlc/l4t-gcc-toolchain-64-bit-28-2-ga2、安装工具链,通过下面的命令来安装工具链。sudo mkdir /opt/..._tx2 内核编译

谷粒商城p45-自动装配-stream流-lambda表达式-程序员宅基地

文章浏览阅读910次。Autowired注入方式是byType,如果只有一个实现类,会装配那个实现类。如果有两个实现类,会报错。@Resource(name="实现类名")//也可以@Resource。@Resource默认按照byName,找不到再byType。自动装配CategoryService对象。调用对象中的listWithTree()@Qualifier("实现类名")@Qualifier 也是 byName。

eclipse junit_掌握Eclipse和JUnit成为更好的Java开发人员的10条最佳课程-程序员宅基地

文章浏览阅读180次。eclipse junit Eclipse和JUnit是Java开发人员的两个基本工具。 Eclipse是Java IDE集成开发环境,可让您 JUnit是一个单元测试库,它允许您自动测试Java代码,从而可以在一个窗口中执行代码,运行和调试Java程序。 您可以编写JUnit测试 ,然后可以在构建时使用Maven或Gradle插件自动运行它们。 您可以使用Jenkins进一步自动化您的构..._在eclipse集成开发环境使用junit.

随便推点

Linux创建二进制文件-cat-程序员宅基地

文章浏览阅读5.2k次。Linux创建二进制文件有如下几种命令:1.通过vi或vim创建:vi/vim 文件名 例如:vim main.cpp //创建源文件main vi 1.txt //创建一个新文件1.txt2.通过touch创建: touch 文件名 touch 1.txt //创建一个新文件3.通过cat重定向创建: cat &gt;文件名 例如..._linux创建二进制文件

数据分析复盘报告,用Excel轻松搞掂!_游资复盘excel-程序员宅基地

文章浏览阅读1k次。说在前面:大家好,我是爱学习的小xiong熊妹。才6月第一周,我的领导,作为大厂的得力基层领导,就迫不及待地让我开始写上半年复盘报告了,我真的是一口气差点上不来~我们知道,做数据分析一般有3个场景:事前:策划类分析、预测类分析事中:监控类分析、原因类分析事后:总结性分析到了6月份,有很多的半年总结、季度总结要做,618大促销的总结也要做。估计近期事后总结性分析报告(或者叫复盘报告)非常多,今天小熊妹就为大家整理了复盘报告的极简分析思路,帮助还在苦苦憋..._游资复盘excel

C++11 wstring、string、utf-8、utf-16之间的相互转换_utf16string-程序员宅基地

文章浏览阅读6.9k次。// C++11_wstring_string.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include &lt;locale&gt;#include &lt;codecvt&gt;#include &lt;iostream&gt;#include &lt;string&gt;#include &lt;windows.h&gt;std..._utf16string

Mac安装openjdk8 教程_mac openjdk8-程序员宅基地

文章浏览阅读1.1k次。参考链接 https://www.cnblogs.com/jimmyshan-study/p/10978533.html_mac openjdk8

java if 用法详解_Java if判断语句用法详解-程序员宅基地

文章浏览阅读2.4k次。Java if判断语句用法详解if关键字中文意思是如果,其细致的语法归纳来说总共有三种:if语句、if-else语句和if-else if-else语句,下面重点介绍if语句。if语句语法if(条件表达式){功能代码块;}功能说明if是该语句中的关键字,后续紧跟一对小括号,该对小括号任何时候不能省略,小括号的内部是具体的条件,语法上要求该表达式结果为boolean类型。后续为功能的代码,也就是当条..._javaif语句的用法

整数因数分解方法_给出n个整数,分解出它们的因数。-程序员宅基地

文章浏览阅读669次。波拉德的 ρ 算法是整数分解的一种算法,是约翰 · 波拉德在1975年发明的。它只占用了很少的空间,并且它的预期运行时间与被分解的合数的最小质因数大小的平方根成正比。根据提示,补全右侧编辑器中 Begin-End 区间的代码,给定一个 n,输出小于等于 n 的所有素数。本关任务:编写一个简单的素数筛法,求解小于等于n所有素数。本关任务:编写一个程序计算给定 n 的“尾巴”和“圈”。为了完成本关任务,你需要掌握:Dixon的随机平方算法。本关任务:根据输入的n以及同余方程输出n的一个因子。_给出n个整数,分解出它们的因数。

推荐文章

热门文章

相关标签