写点什么

AI 语音处理 - 文字合成语音功能

作者:DS小龙哥
  • 2022 年 3 月 11 日
  • 本文字数:4192 字

    阅读完需:约 14 分钟

1. 前言

语音合成技术在生活中用越来越广泛,阅读听书、订单播报、智能硬件、语音导航 很多场景下都加入了语音播报功能。语音合成基于深度神经网络技术,提供高度拟人、流畅自然的语音合成服务,可以模拟出不同人的声音,让应用 APP、设备开口说话,还能智能化训练个性语音。


这篇文章就介绍华为云提供的语音合成服务使用方法,利用提供的 API 接口完成语音合成功能,将合成的语音下载下来。



2. 开通功能

华为云的提供的语音合成,是一种将文本转换成逼真语音的服务。用户通过实时访问和调用 API 获取语音合成结果,将用户输入的文字合成为音频。通过音色选择、自定义音量、语速,为企业和个人提供个性化的发音服务。

2.1 语音交互服务

**地址:**https://console.huaweicloud.com/sis/?region=cn-north-4#/sis/stts


2.2 帮助文档

地址: https://support.huaweicloud.com/api-sis/sis_03_0111.html



(1)请求 Header 参数:



请求头里的 X-Auth-Token 字段在之前的文章已经介绍过,获取方法看这里: https://bbs.huaweicloud.com/blogs/317759 翻到 2.3 小节。


(2)请求 Body 参数:



(3)TtsConfig 的配置参数:



(4)普通发音人 property 取值范围:



(5)精品发音人 property 取值范围:



(6)响应的 Body 参数


状态码: 200



(7)CustomResult 参数


2.3 在线调试接口

通过在线调试接口,可以快速调试接口参数,请求方式,返回结果等信息。


地址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=SIS&api=RunTts



还可以在线填入测试参数,进行测试效果。


2.4 请求接口总结

请求地址格式: POST /v1/{project_id}/tts

完整请求地址:https://sis-ext.cn-north-4.myhuaweicloud.com/v1/0e5957be8a00f53c2fa7c0045e4d8fbf/tts
请求体:{ "text": "请注意坐姿", "config": { "audio_format": "wav", "sample_rate": "16000", "property": "chinese_xiaoqi_common", "speed": 0, "pitch": 0, "volume": 0 }}

请求头:{ "X-Auth-Token": "******", "Content-Type": "application/json;charset=UTF-8"}
响应体:{"result":{"data":xxxxxxxx"}}
这个xxxx就是返回的Base64编码语音数据,可以解码后保存成文件即可。
复制代码

3. 实现源码

软件采用 QT 设计的,核心部分主要是用到了 HTTP 请求相关的操作。



3.1 文字转语音源码

//文本转语音void Widget::TextToAudio(QString text){    function_select=1;    QString requestUrl;    QNetworkRequest request;
//设置请求地址 QUrl url;
//请求地址 requestUrl = QString("https://sis-ext.%1.myhuaweicloud.com/v1/%2/tts") .arg(SERVER_ID) .arg(PROJECT_ID);
//设置数据提交格式 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//设置token request.setRawHeader("X-Auth-Token",Token);
//构造请求 url.setUrl(requestUrl); request.setUrl(url);
QString post_param=QString ("{" "\"text\": \"%1\"," "\"config\": {" "\"audio_format\": \"%2\"," "\"sample_rate\": \"%3\"," "\"property\": \"%4\"," "\"speed\": %5," "\"pitch\": 0," "\"volume\": %6" "}" "}").arg(text).arg(ui->comboBox_formt->currentText()) .arg(ui->comboBox_cai_yang_lv->currentText()) .arg(ui->comboBox_fa_yin_ren->currentText()) .arg(ui->spinBox_audio_speed->value()) .arg(ui->spinBox_yin_liang->value());
//发送请求 manager->post(request, post_param.toUtf8());}

//生成语音void Widget::on_pushButton_to_audio_clicked(){ QString text=ui->lineEdit->text(); if(text.isEmpty()) { QMessageBox::information(this,"提示","请输入文本", QMessageBox::Ok,QMessageBox::Ok); return; } qDebug()<<"text:"<<text; TextToAudio(text);}
复制代码

3.2 获取 token

/*功能: 获取token*/void Widget::GetToken(){    //表示获取token    function_select=3;
QString requestUrl; QNetworkRequest request;
//设置请求地址 QUrl url;
//获取token请求地址 requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens") .arg(SERVER_ID);
//自己创建的TCP服务器,测试用 //requestUrl="http://10.0.0.6:8080";
//设置数据提交格式 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));
//构造请求 url.setUrl(requestUrl);
request.setUrl(url);
QString text =QString("{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":" "{\"user\":{\"domain\": {" "\"name\":\"%1\"},\"name\": \"%2\",\"password\": \"%3\"}}}," "\"scope\":{\"project\":{\"name\":\"%4\"}}}}") .arg(MAIN_USER) .arg(IAM_USER) .arg(IAM_PASSWORD) .arg(SERVER_ID);
//发送请求 manager->post(request, text.toUtf8());}
复制代码

3.3 解析返回值

//解析反馈结果void Widget::replyFinished(QNetworkReply *reply){    QString displayInfo="";
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
//读取所有数据 QByteArray replyData = reply->readAll();
qDebug()<<"状态码:"<<statusCode; qDebug()<<"反馈的数据:"<<QString(replyData);
//更新token if(function_select==3) { displayInfo="token 更新失败."; //读取HTTP响应头的数据 QList<QNetworkReply::RawHeaderPair> RawHeader=reply->rawHeaderPairs(); qDebug()<<"HTTP响应头数量:"<<RawHeader.size(); for(int i=0;i<RawHeader.size();i++) { QString first=RawHeader.at(i).first; QString second=RawHeader.at(i).second; if(first=="X-Subject-Token") { Token=second.toUtf8(); displayInfo="token 更新成功.";
//保存到文件 SaveDataToFile(Token); break; } } QMessageBox::information(this,"提示",displayInfo, QMessageBox::Ok,QMessageBox::Ok); return; }
//判断状态码 if(200 != statusCode) { //解析数据 QJsonParseError json_error; QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error); if(json_error.error == QJsonParseError::NoError) { //判断是否是对象,然后开始解析数据 if(document.isObject()) { QString error_str=""; QJsonObject obj = document.object(); QString error_code; //解析错误代码 if(obj.contains("error_code")) { error_code=obj.take("error_code").toString(); error_str+="错误代码:"; error_str+=error_code; error_str+="\n"; } if(obj.contains("error_msg")) { error_str+="错误消息:"; error_str+=obj.take("error_msg").toString(); error_str+="\n"; }
QMessageBox::information(this,"提示",error_str, QMessageBox::Ok,QMessageBox::Ok); } } return; }
else if(function_select==1) //语音合成 { //解析数据 QJsonParseError json_error; QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error); if(json_error.error == QJsonParseError::NoError) { //判断是否是对象,然后开始解析数据 if(document.isObject()) { QJsonObject obj = document.object(); //解析错误代码 if(obj.contains("result")) { QJsonObject obj1=obj.take("result").toObject();
if(obj1.contains("data")) { QString data=obj1.take("data").toString(); QByteArray d2=QByteArray::fromBase64(data.toUtf8()); qDebug()<<"数据获取成功..";
QStringList path_list=QStandardPaths::standardLocations(QStandardPaths::DownloadLocation);
//保存到文件 QString filename=QFileDialog::getSaveFileName(this,"保存音频文件",path_list.at(0),tr("*.wav *.mp3 *.pcm")); if(filename.isEmpty()) { filename=path_list.at(0)+"/123.wmv"; }
QFile::remove(filename);
QFile file_2(filename); file_2.open(QIODevice::WriteOnly); file_2.write(d2); //写入数据 file_2.close(); } } } } }}
复制代码


发布于: 刚刚阅读数: 2
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
AI语音处理-文字合成语音功能_3月月更_DS小龙哥_InfoQ写作平台