20.5 语音合成(百度2016年2月29日发布的tts引擎)

一、简介

编写手机App时,有时需要使用文字转语音(Text to Speech)的功能,比如开车时阅读收到的短信、导航语音提示、界面中比较重要的信息通过语音强调、……等。

由于Android自带的Pico TTS并不支持中文,所以要既能阅读中文文本,还能阅读英文文本,必须下载第三方提供的能说中文的语音包。

二、申请百度tts授权

本节以百度2016年2月29日发布的“离在线融合语音合成SDK_Android 2.2.3版”为例说明用C#实现语音合成的基本用法。之所以选择百度语音合成来实现,是因为据百度官网声明,该开发包是“永久免费”的。网址如下:

http://yuyin.baidu.com/tts/

由于原来已经申请过MyDemos的授权,所以再继续申请tts授权就比较简单了,申请和设置步骤如下。

1、申请授权

进入 http://yuyin.baidu.com/tts/ 的首页:

单击【立即使用】,进入“开通语音合成服务”的页面:

在下拉框中选择原来已经申请的某个应用,单击【下一步】,然后按提示操作,开通离线服务即可。

2、在BdMapV371BindingLib项目中转换JAR文件

先通过 http://yuyin.baidu.com/tts/ 首页中的【相关下载】下载对应的开发包,然后再按下面的步骤操作。

1、将示例中的com.baidu.tts_2.2.3.20160229_359d952_release.jar、galaxy-v2.0.jar添加到Jars文件夹下,如下图所示,然后将其【生成操作】属性全部设置为“EmbeddedJar”。

2、在Metadata.xml文件中添加下面的语句:

<remove-node path="/api/package[@name='com.baidu.tts.aop']/interface[@name='IProxyFactory']/method[@name='createProxied' and count(parameter)=0]" /> 

3、重新生成项目,此时应该无错误。

经过这3个步骤,就完成了tts的Jar包导入和转换为.cs文件的过程。

3、在MyDemos项目中添加.so文件

将tts相关的4个.so文件添加到MyDemos项目的x86文件夹下,如下图所示,然后将其【生成操作】属性全部设置为“AndroidNativeLibrary”。

4、将.dat文件添加到sd卡的BaiduTTS文件夹下

具体添加办法见【常见问题解答】,这里不再截图。

也可以先将这些文件添加到Assets文件夹下,然后通过代码将其复制到sd卡的文件夹下。为简化起见,这里通过手工直接复制了。

OK,经过上面这4步,以后就可以在MyDemos项目中的任何模块中轻松利用百度tts实现语音阅读的功能了

三、示例

1、运行截图

单击【阅读】,就会自动用女音朗读文本框中的内容,单击【批量阅读】,就会依次朗读队列中添加的文字段(主要是为了演示阅读各种不同的中英文短句)。

2、设计步骤

(1)添加ch2005Main.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:weightSum="4">
<Button
android:id="@+id/speak"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="阅读"
android:textSize="12dp" />
<Button
android:id="@+id/pause"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="暂停"
android:textSize="12dp" />
<Button
android:id="@+id/resume"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="继续"
android:textSize="12dp" />
<Button
android:id="@+id/stop"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="停止"
android:textSize="12dp" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:weightSum="4">
<Button
android:id="@+id/synthesize"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="synthesize"
android:textSize="12dp" />
<Button
android:id="@+id/play"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="play"
android:textSize="12dp" />
<Button
android:id="@+id/batchSpeak"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:text="批量阅读"
android:textSize="12dp" />
<Button
android:id="@+id/nextActivity"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:lines="2"
android:enabled="false"
android:text="备用"
android:textSize="12dp" />
</LinearLayout>
<EditText
android:id="@+id/input"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="input" />
<TextView
android:id="@+id/showText"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="10dp"
android:background="@android:color/darker_gray"
android:minLines="3"
android:scrollbars="vertical" />
</LinearLayout>

2、添加ch2005MainActivity.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.OS;
using Android.Widget;
using Com.Baidu.Tts.Client;
using Com.Baidu.Tts.Answer.Auth;
namespace MyDemos.SrcDemos
{
[Activity(Label = "【例20-5】百度tts基本用法")]
public class ch2005MainActivity : Activity, ISpeechSynthesizerListener
{
private EditText mInput;
private TextView mShowText;
private SpeechSynthesizer mSpeechSynthesizer;
/// <summary>
/// sd卡上保存百度tts文件的路径
/// </summary>
private string mSampleDirPath;
private const string SpeechFemaleModelName = "bd_etts_speech_female.dat";
private const string SpeechMaleModelName = "bd_etts_speech_male.dat";
private const string TextModelName = "bd_etts_text.dat";
private const string EnglishSpeechFemaleModelName = "bd_etts_speech_female_en.dat";
private const string EnglishSpeechMaleModelName = "bd_etts_speech_male_en.dat";
private const string EnglishTextModelName = "bd_etts_text_en.dat";
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.ch2005Main);
mSampleDirPath = Android.OS.Environment.ExternalStorageDirectory.Path + "/baiduTTS";
Console.WriteLine("mSampleDirPath=" + mSampleDirPath);
initialView();
initialTts();
}
private void initialTts()
{
mSpeechSynthesizer = SpeechSynthesizer.Instance;
mSpeechSynthesizer.SetContext(this);
mSpeechSynthesizer.SetSpeechSynthesizerListener(this);
// 文本模型文件路径 (离线引擎使用)
mSpeechSynthesizer.SetParam(SpeechSynthesizer.ParamTtsTextModelFile,
mSampleDirPath + "/" + TextModelName);
// 声学模型文件路径 (离线引擎使用)
mSpeechSynthesizer.SetParam(SpeechSynthesizer.ParamTtsSpeechModelFile,
mSampleDirPath + "/" + SpeechFemaleModelName);
// 请替换为语音开发者平台上注册应用得到的App ID (离线授权)
//mSpeechSynthesizer.SetAppId("your_app_id");
mSpeechSynthesizer.SetAppId(ch.TtsAppID);
// 请替换为语音开发者平台注册应用得到的apikey和secretkey (在线授权)
//this.mSpeechSynthesizer.SetApiKey("your_api_key", "your_secret_key");
this.mSpeechSynthesizer.SetApiKey(ch.TtsApiKey, ch.TtsSecretKey);
// 发音人(在线引擎),可用参数为0,1,2,3。。。(服务器端会动态增加,各值含义参考文档,以文档说明为准。0--普通女声,1--普通男声,2--特别男声,3--情感男声。。。)
mSpeechSynthesizer.SetParam(SpeechSynthesizer.ParamSpeaker, "0");
// 设置Mix模式的合成策略
mSpeechSynthesizer.SetParam(SpeechSynthesizer.ParamMixMode, SpeechSynthesizer.MixModeDefault);
// 授权检测接口(可以不使用,只是验证授权是否成功)
AuthInfo authInfo = this.mSpeechSynthesizer.Auth(TtsMode.Mix);
if (authInfo.IsSuccess)
{
Console.WriteLine("授权检测--授权成功(auth success)。");
}
else
{
string errorMsg = authInfo.TtsError.DetailMessage;
Console.WriteLine("授权检测--授权失败(auth failed),errorMsg=" + errorMsg);
}
// 初始化tts
mSpeechSynthesizer.InitTts(TtsMode.Mix);
// 加载离线英文资源(提供离线英文合成功能)
int result = mSpeechSynthesizer.LoadEnglishModel(
mSampleDirPath +
"/" + EnglishTextModelName, mSampleDirPath +
"/" + EnglishSpeechFemaleModelName);
}
private void initialView()
{
mInput = FindViewById<EditText>(Resource.Id.input);
mInput.Text = "今天阳光明媚,风和日丽!";
mShowText = FindViewById<TextView>(Resource.Id.showText);
var speak = FindViewById<Button>(Resource.Id.speak);
speak.Click += delegate
{
string text = this.mInput.Text;
int result = this.mSpeechSynthesizer.Speak(text);
if (result < 0)
{
System.Diagnostics.Debug.WriteLine("出错了,错误码:{0},请检查百度tts文档中对应错误码的含义。", result);
}
};
var pause = FindViewById<Button>(Resource.Id.pause);
pause.Click += delegate
{
mSpeechSynthesizer.Pause();
};
var resume = FindViewById<Button>(Resource.Id.resume);
resume.Click += delegate
{
mSpeechSynthesizer.Resume();
};
var stop = FindViewById<Button>(Resource.Id.stop);
stop.Click += delegate
{
mSpeechSynthesizer.Stop();
};
var synthesize = FindViewById<Button>(Resource.Id.synthesize);
synthesize.Click += delegate
{
string text = this.mInput.Text;
int result = this.mSpeechSynthesizer.Synthesize(text);
if (result < 0)
{
System.Diagnostics.Debug.WriteLine("error,please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 ");
}
};
var play = FindViewById<Button>(Resource.Id.play);
play.Click += delegate { };
var batchSpeak = FindViewById<Button>(Resource.Id.batchSpeak);
batchSpeak.Click += delegate
{
List<SpeechSynthesizeBag> bags = new List<SpeechSynthesizeBag>();
bags.Add(GetSpeechSynthesizeBag("123456", "0"));
bags.Add(GetSpeechSynthesizeBag("你好", "1"));
bags.Add(GetSpeechSynthesizeBag("使用百度语音合成SDK", "2"));
bags.Add(GetSpeechSynthesizeBag("hello", "3"));
bags.Add(GetSpeechSynthesizeBag("这是一个demo工程", "4"));
int result = this.mSpeechSynthesizer.BatchSpeak(bags);
if (result < 0)
{
System.Diagnostics.Debug.WriteLine("error({0}),please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 ", result);
}
};
}
protected override void OnDestroy()
{
base.OnDestroy();
}
private SpeechSynthesizeBag GetSpeechSynthesizeBag(string text, string utteranceId)
{
SpeechSynthesizeBag speechSynthesizeBag = new SpeechSynthesizeBag();
speechSynthesizeBag.SetText(text);
speechSynthesizeBag.UtteranceId = utteranceId;
return speechSynthesizeBag;
}
public void OnError(string utteranceId, SpeechError error)
{
Console.WriteLine("onError error=" + error.Description + "--utteranceId=" + utteranceId);
}
public void OnSpeechFinish(string utteranceId)
{
Console.WriteLine("onSpeechFinish utteranceId=" + utteranceId);
}
public void OnSpeechProgressChanged(string p0, int p1)
{
//Console.WriteLine("onSpeechProgressChanged");
}
public void OnSpeechStart(string utteranceId)
{
Console.WriteLine("onSpeechStart utteranceId=" + utteranceId);
}
public void OnSynthesizeDataArrived(string utteranceId, byte[] data, int progress)
{
Console.WriteLine("onSynthesizeDataArrived");
}
public void OnSynthesizeFinish(string utteranceId)
{
Console.WriteLine("onSpeechFinish utteranceId=" + utteranceId);
}
public void OnSynthesizeStart(string utteranceId)
{
Console.WriteLine("onSynthesizeStart utteranceId=" + utteranceId);
}
}
}
(0)

相关推荐

  • 20.5 语音合成(百度2016年2月29日发布的tts引擎)

    一.简介 编写手机App时,有时需要使用文字转语音(Text to Speech)的功能,比如开车时阅读收到的短信.导航语音提示.界面中比较重要的信息通过语音强调.--等. 由于Android自带的Pico TTS并不支持中文,所以要既能阅读中文文本,还能阅读英文文本,必须下载第三方提供的能说中文的语音包. 二.申请百度tts授权 本节以百度2016年2月29日发布的"离在线融合语音合成SDK_Android 2.2.3版"为例说明用C#实现语音合成的基本用法.之所以选择百度语音合成来

  • 2013年国家法定节假日安排 春节假期2月9日至15日

    国务院办公厅关于2013年部分节假日安排的通知 国办发明电[2012]33号 各省.自治区.直辖市人民政府,国务院各部委.各直属机构: 根据国务院<关于修改<全国年节及纪念日放假办法>的决定>,为便于各地区.各部门及早合理安排节假日旅游.交通运输.生产经营等有关工作,经国务院批准,现将2013年元旦.春节.清明节.劳动节.端午节.中秋节和国庆节放假调休日期的具体安排通知如下. 一.元旦: 1月1日至3日放假调休,共3天.1月5日(星期六).1月6日(星期日)上班. 二.春节: 2月

  • WebGame《逆转裁判》完整版 代码下载(1月24日更新)

    特别提醒:您可以自由下载并更改代码,欢迎所有有志于WebGame领域的朋友给我写信或到我的Blog上留言. 演示地址:http://nzcp.gbq.cn/screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" on

  • 万圣节是什么节日 2014万圣节是几月几日

    2014万圣节是几月几日?万圣节是什么时候?万圣节是什么节? 答: 2014万圣夜:10月31日 2014年万圣节:11月1日 我们一般说的过万圣节就是过万圣夜,这一天一些游乐场所都非常热闹.像上海的欢乐谷等... 万圣节(Hallowmas) "杰克灯"(南瓜灯)的样子十分可爱,做法也极为简单.将南瓜掏空,然后在外面刻上笑眯眯的眼睛和大嘴巴,再在瓜中插上一支蜡烛,把它点燃,人们在很远的地方便能看到这张憨态可掬的笑脸.这可是孩子们最喜欢的玩物了. 节日起源 第一种说法 方法法关于万圣节

  • 清明节是几月几日 清明节的由来

    2012年是4月5日 清明节是根据二下四节气来推算的.所以不一定每年的清明节都是4月4日.清明是二十四节气之一,清明节就在清明那一天,每年的清明大致都在阳历的4月4日至4月6日那天.节气的划分是根据太阳跟赤道的角度来定的,因此农历也没有一定的日子. 2010的清明节是4月5日 2010年清明节放假时间:4月4日至5日放假,共3天.其中,4月3日(星期六),4月4日(星期日)照常公休.4月5日(星期一,农历清明当日)为法定节假日. 清明,农历二十四节气之一.中国传统的清明节大约始于周代,距今已有二

  • 教你用python从日期中获取年、月、日和星期等30种信息

    目录 1 计算日期的年月日时分秒,星期,周次… 2计算一年中的第几天, 第几个10分钟, 日期转数值 3判断日期是否闰年,年初年末,月初月末… 4字符串时段,季节 5for循环快捷计算 6时间间隔天数计算 补充:Python日期获取今天及昨天的年月日等信息 总结 这次介绍日期数据处理. 用python中的方法对日期数据进行处理, 我们可以获取很多有用的信息, 比如年月日,星期,周次,季度等, 这里分享工作和数据竞赛30余种常用的转换方法. 1 计算日期的年月日时分秒,星期,周次… 用pandas

  • MySQL按年/月/周/日/小时分组查询、排序、limit及判空用法实例

    目录 一.按年/月/周/日/小时分组查询(日期时间类型为date或者datetime) 二.MySQL排序 1.排序规则 2.单列排序 三.limit 详细用法 1.用于强制返回指定的记录行数 2.分页 四.ifnull()函数的使用 1.ifnull()的语法 2.ifnull()的使用 总结 一.按年/月/周/日/小时分组查询(日期时间类型为date或者datetime) 在DATE_FORMAT(create_time,'%Y%m%d')中设置需要分组的类型和格式,如下: '%Y%m%d'

  • php计算两个日期时间差(返回年、月、日)

    在PHP程序中,很多时候都会遇到处理时间的问题,比如:判断用户在线了多长时间,共登录了多少天,两个帖子发布的时间差或者是不同操作之间的日志记录等等.在文章中,简单地举例介绍了PHP中如何计算两个日期相差 年.月.日. <?php /** +---------------------------------------------------------- * 功能:计算两个日期相差 年 月 日 +--------------------------------------------------

  • 计算2000年01月01日起到指定日的天数

    这是一个计算2000年01月01日起到指定日的天数的函数 <br> (算头也算尾)日期格式为:YYYY-MM-DD <br> <?php //    计算从2000年01月01日开始到某日的天数 function cal_start2end($end_day,$start_day) { $start_day=ereg_replace("-","",$start_day); $end_day=ereg_replace("-&qu

  • 植树节是几月几日,植树节的的由来和意义整理

    中国: 每年3月12日为植树节 ; 朝鲜: 每年3月2日为植树节; 印度: 每年7月第一周开展全国植树节活动; 斯里兰卡:9月17日为植树节; 泰国:国庆节定为植树节; 菲律宾: 每年9月第二个星期六为植树节; 约旦:1月15日是植树节; 巴勒斯坦:1月6日是植树节; 埃及: 每年9月至11月为植树节; 巴西: 每年9月21日为植树节; 墨西哥: 每年6至9月的雨季里开展植树节活动; 哥伦比亚: 每年10月12日为植树节; 萨尔瓦多: 每年的6月21日举行; 法国: 每年3月为法定的绿化月,3月

随机推荐