科大讯飞离线lunix tts demo使用

项目中需要用到后台服务端用文本生成语音,网上大部分都是通过ai大模型推理出来的,还有写其他方式的,效果和生成时间都比较不理想,但是讯飞生成的只需要零点几秒,不愧是行业NO1,下面说下怎么使用。

1、下载官方demo。

2、在官方demo目录下,执行source 32bit_make.sh 或64bit_make.sh ,根据你的位数来。

3、执行后,不报错的情况下在bin目录下就会生成可执行文件,直接执行 ./tts_offline_sample就可以测试生成结果。

4、在项目中使用,这样肯定是不行的,在demo目录下的.c文件就要改造一下。

/*
* 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的
* 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的
* 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。
*/#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>  
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include "../include/qtts.h"
#include "../include/msp_cmn.h"
#include "../include/msp_errors.h"
typedef int SR_DWORD;
typedef short int SR_WORD ;/* wav音频头部格式 */
typedef struct _wave_pcm_hdr
{char            riff[4];                // = "RIFF"int                size_8;                 // = FileSize - 8char            wave[4];                // = "WAVE"char            fmt[4];                 // = "fmt "int                fmt_size;                // = 下一个结构体的大小 : 16short int       format_tag;             // = PCM : 1short int       channels;               // = 通道数 : 1int                samples_per_sec;        // = 采样率 : 8000 | 6000 | 11025 | 16000int                avg_bytes_per_sec;      // = 每秒字节数 : samples_per_sec * bits_per_sample / 8short int       block_align;            // = 每采样点字节数 : wBitsPerSample / 8short int       bits_per_sample;        // = 量化比特数: 8 | 16char            data[4];                // = "data";int                data_size;              // = 纯数据长度 : FileSize - 44 
} wave_pcm_hdr;/* 默认wav音频头部数据 */
wave_pcm_hdr default_wav_hdr = 
{{ 'R', 'I', 'F', 'F' },0,{'W', 'A', 'V', 'E'},{'f', 'm', 't', ' '},16,1,1,16000,32000,2,16,{'d', 'a', 't', 'a'},0  
};
/* 文本合成 */
int text_to_speech(const char* src_text, const char* des_path, const char* params)
{int          ret          = -1;FILE*        fp           = NULL;const char*  sessionID    = NULL;unsigned int audio_len    = 0;wave_pcm_hdr wav_hdr      = default_wav_hdr;int          synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;if (NULL == src_text || NULL == des_path){printf("params is error!\n");return ret;}fp = fopen(des_path, "wb");if (NULL == fp){printf("open %s error.\n", des_path);return ret;}/* 开始合成 */sessionID = QTTSSessionBegin(params, &ret);if (MSP_SUCCESS != ret){printf("QTTSSessionBegin failed, error code: %d.\n", ret);fclose(fp);return ret;}ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL);if (MSP_SUCCESS != ret){printf("QTTSTextPut failed, error code: %d.\n",ret);QTTSSessionEnd(sessionID, "TextPutError");fclose(fp);return ret;}fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000while (1) {/* 获取合成音频 */const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);if (MSP_SUCCESS != ret)break;if (NULL != data){fwrite(data, audio_len, 1, fp);wav_hdr.data_size += audio_len; //计算data_size大小}if (MSP_TTS_FLAG_DATA_END == synth_status)break;}printf("\n");if (MSP_SUCCESS != ret){printf("QTTSAudioGet failed, error code: %d.\n",ret);QTTSSessionEnd(sessionID, "AudioGetError");fclose(fp);return ret;}/* 修正wav文件头数据的大小 */wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8);/* 将修正过的数据写回文件头部,音频文件为wav格式 */fseek(fp, 4, 0);fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值fclose(fp);fp = NULL;/* 合成完毕 */ret = QTTSSessionEnd(sessionID, "Normal");if (MSP_SUCCESS != ret){printf("QTTSSessionEnd failed, error code: %d.\n",ret);}return ret;
}int ensure_directory_exists(const char* path) {  // 使用F_OK检查文件(或文件夹)是否存在  if (access(path, F_OK) != -1) {  // 路径存在,可能是文件或文件夹,但我们假设它是文件夹(这里不进一步区分)  return 0; // 成功,路径已存在  } else {  // 路径不存在,尝试创建文件夹  // 注意:mkdir的第二个参数设置了文件夹的权限(如0755表示rwxr-xr-x)  if (mkdir(path, 0755) != 0) {  // 创建文件夹失败  perror("mkdir failed");  return -1; // 失败  }  }  return 0; // 成功(无论是已存在还是新创建)  
} char* create_filename(const char* file_path) {  const char* base_path = "/tts/";  char date_str[11]; // "YYYY_MM_DD"格式最多需要10个字符+1个空字符  char directory_path[256]; // 足够大的缓冲区来存储完整路径  // 获取当前日期并格式化为"YYYY_MM_DD"  time_t rawtime;  struct tm *timeinfo;  time(&rawtime);  timeinfo = localtime(&rawtime);  strftime(date_str, sizeof(date_str), "%Y_%m_%d", timeinfo);  // 构建完整路径  snprintf(directory_path, sizeof(directory_path), "%s%s%s", base_path, date_str,"/");  ensure_directory_exists(directory_path);const char* extension = ".wav";  // 计算所需的总长度(包括null终止符)  size_t total_length = strlen(directory_path) + strlen(file_path) + strlen(extension) + 1;  // 动态分配内存来存储完整的文件名  char* filename = (char*)malloc(total_length * sizeof(char));  if (filename == NULL) {  perror("malloc failed");  return NULL; // 内存分配失败时返回NULL  }  // 使用snprintf来安全地拼接字符串  snprintf(filename, total_length, "%s%s%s", directory_path, file_path, extension);  return filename;  
}  int main(int argc, char* argv[])
{/*解析入口参数*//**tts文本*/const char* tts_txt = argv[1];   printf(tts_txt);printf("\n");/*生成文件存储文件名字*/const char* file_path=argv[2];printf(file_path);printf("\n");/*tts发声参数*/const char* tts_param=argv[3];printf(tts_param);printf("\n");int         ret                  = MSP_SUCCESS;const char* login_params         = "appid = 换成你自己的, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动/** rdn:           合成音频数字发音方式* volume:        合成音频的音量* pitch:         合成音频的音调* speed:         合成音频对应的语速* voice_name:    合成发音人* sample_rate:   合成音频采样率* text_encoding: 合成文本编码格式**/const char* session_begin_params = tts_param;printf(session_begin_params);const char* filename             =  create_filename(file_path); const char* text                 = tts_txt; /* 用户登录 */ret = MSPLogin(NULL, NULL, login_params); //第一个参数是用户名,第二个参数是密码,第三个参数是登录参数,用户名和密码可在http://www.xfyun.cn注册获取if (MSP_SUCCESS != ret){printf("MSPLogin failed, error code: %d.\n", ret);MSPLogout(); //退出登录return 0;}/* 文本合成 */ret = text_to_speech(text, filename, session_begin_params);if (MSP_SUCCESS != ret){printf("text_to_speech failed, error code: %d.\n", ret);}MSPLogout(); //退出登录return 0;
}

5、再执行第二步的操作。

6、在bin目录下新建tts_test.sh脚本用于测试,也可以不用,直接执行内容的命令,内容如下

tts_offline_sample "tts测 试 " ewr5we "engine_type = local,voice_name=xiaoyan, text_encoding = UTF8, tts_res_
path = fo|res/tts/xiaoyan.jet;fo|res/tts/common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 5
0, rdn = 2"

 执行新建的脚本测试。

7、bin目录下的msc目录下的msc.cfg文件直接删除,不然会有很多的日志。

8、脚本执行可以的话,C语言的开发就到这里了,用其他语言发起命令行调用就能实现合成了,具体的要看你的业务怎么设计的了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/5615.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

[ DOS 命令基础 ] DOS 命令详解-大集合

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

(61)使用LMS算法估计线性预测器并计算估计误差的MATLAB仿真

文章目录 前言一、仿真说明二、仿真代码三、仿真结果1.LMS自适应滤波器权向量更新曲线2.LMS自适应滤波器算法学习曲线3.期望信号与LMS自适应滤波器输出信号 前言 本文介绍了LMS自适应滤波器对线性预测器系统权系数的估计&#xff0c;进行100次独立实验&#xff0c;计算平均估计…

C语言进阶2:指针的进阶

文章目录 1.字符指针2.指针数组3.数组指针3.1 数组指针的定义3.2 &数组名VS数组名3.3 数组指针的使用3.3.1 对一维数组的使用3.3.2 对二维数组的使用3.3.3 巩固练习 4.数组参数、指针参数4.1 一维数组传参4.2 二维数组传参4.3 一级指针传参4.4 二级指针传参 5.函数指针6.函…

初级图像处理工具

图像处理-初级 1、功能概览 初级图像处理工具旨在为用户提供一个易于使用的界面来执行常见的图像处理任务。该工具集成了多项实用功能&#xff0c;从显示和调整图像的基本属性到应用各种滤镜效果&#xff0c;用户都可以通过简单的命令行交互来完成。 我们的初级图像处理工具…

【C语言】实战-力扣题库:回文链表

题目描述 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 提示&#xff1a; 链表中节点数目在范围[1, 105] 内0 < Node.val < 9 进阶&#xff1a;你能否用 O(n) 时间…

Flink滑动窗口(Sliding)中window和windowAll的区别

滑动窗口的使用&#xff0c;主要是计算&#xff0c;在reduce之前添加滑动窗口&#xff0c;设置好间隔和所统计的时间&#xff0c;然后再进行reduce计算数据即可。 窗口设置好时间间隔&#xff0c;和处理时间窗口的时间&#xff0c;比如将滑动窗口的时间间隔都设置为5s,处理时间…

AWS云服务器选择哪个区域最好?

选择AWS云服务器的区域&#xff08;Region&#xff09;是一个非常重要的决策&#xff0c;因为它会影响你的应用性能、成本和合规性。以下是九河云总结的一些选择AWS区域时需要考虑的关键因素&#xff1a; 1. 地理位置和延迟 选择离你的用户或客户最近的区域可以最大程度减少网…

高频面试题(含笔试高频算法整理)基本总结回顾30

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

6.气泵控制原理---单双向可控硅控制原理、斩波电路、项目举例说明

最近在项目开发中&#xff0c;涉及到气泵的相关控制&#xff0c;在这里进行比较系统的学习。对交直流气泵区别进行一个说明 &#xff0c;同时了解一下单向和双向可控硅&#xff0c;最后根据项目实例进行了解。因为个人比较偏软件&#xff0c;有什么不对的地方欢迎指正。 一交流…

element-plus table tableRowClassName 无效

官网上给的是 .el-table .warning-row {--el-table-tr-bg-color: var(--el-color-warning-light-9); } .el-table .success-row {--el-table-tr-bg-color: var(--el-color-success-light-9); } 但是 如果 加上了 scoped 这样样式是无效的 在 vue3 中用样式穿透 即可生…

Python自动化测试框架详解!

随着技术的进步和自动化技术的出现&#xff0c;市面上出现了一些自动化测试框架。只需要进行一些适用性和效率参数的调整&#xff0c;这些自动化测试框架就能够开箱即用&#xff0c;大大节省了开发时间。而且由于这些框架被广泛使用&#xff0c;他们具有很好的健壮性&#xff0…

【数据结构实战】从0打造你的专属顺序表

专栏&#xff1a;《数据结构实战篇》 生活中有着无穷无尽的数据需要存储&#xff0c;大到全国人口普查&#xff0c;小到微信、QQ好友列表&#xff0c;都需要有一个合理的存储方式才能使得我们的数据更方便管理&#xff0c;线性表就是其中之一 一、线性表 线性表&#xff08;li…

RFID标签实现托盘智能化管理

一、RFID技术概述 1.1 RFID技术原理 RFID技术&#xff0c;即无线射频识别技术&#xff0c;是一种利用无线电波进行非接触式自动识别和数据交换的技术。其核心优势在于能够实现远距离、快速、批量的识别&#xff0c;相较于传统的条形码技术&#xff0c;RFID技术在物资管理领域展…

net core 生成URL HtmlHelper

HtmlHelper Url.Action Url.RouteUrl RedirectToAction public IActionResult Privacy(){return RedirectToAction("Index");}Html.ActionLink Html.BeginForm Html.ActionLink 与 Url.Action 1.两者者是根据给定的Controller,Action 生成链接&#xff0c; 但是H…

零日漏洞被谷歌的 AI 工具发现

谷歌的 AI 研究工具 Big Sleep 取得了重大突破&#xff0c;发现了 SQLite 中的漏洞&#xff0c;SQLite 是全球使用最广泛的数据库引擎之一。 Google Project Zero 和 Google DeepMind 团队最近在官方博客文章中分享了这一里程碑&#xff0c;标志着 AI 驱动的漏洞检测在现实世界…

Github 2024-11-07 Go开源项目日报 Top10

根据Github Trendings的统计,今日(2024-11-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10HTML项目1Kubernetes: 容器化应用程序管理系统 创建周期:3618 天开发语言:Go协议类型:Apache License 2.0Star数量:106913 个Fork数…

Java学习笔记之类

文章目录 类和对象的基础属性/成员变量⚠️ 属性的注意事项和细节⚠️ 构建函数 类和对象的区别类和对象的内存分配机制练习 成员方法方法定义⚠️ 方法使用细节⚠️ 形参列表细节⚠️ 方法内部细节⚠️ 方法调用细节方法入门代码01⚠️ 行参和成员方法重名方法入门代码02方法递…

链表删除相关算法题|删除值为x的节点|删除最小值节点|删除值在区间内的节点|删除重复节点|删除绝对值相等的节点(C)

删除值为x的节点 在带头结点的单链表L中&#xff0c;删除所有值为X的结点&#xff0c;并释放其空间&#xff0c;假设值为的结点不唯一 算法思想 删除单链表的节点需要三个指针 一个是遍历链表的工作指针cur&#xff0c;一个是指向cur的上一个节点的指针prev&#xff0c;一个…

C++:哈希表的实现

一、哈希表的基本概念 1、负载因子&#xff1a;假设哈希表中已经映射存储了N个值&#xff0c;哈希表的大小为M&#xff0c;那么负载因子 N / M&#xff0c;负载因子有些地⽅也翻译为载荷因子/装载因子等&#xff0c;他的英文为load/factor。负载因子越大&#xff0c;哈希冲突的…

2024年11月软考考前注意事项

一、重要时间节点 准考证打印时间&#xff1a; 大部分省市的准考证打印时间从11月4日起开始&#xff0c;但上海、甘肃等地区则稍晚&#xff0c;从11月6日起开放打印。 请务必注意所在地区的具体打印时间&#xff0c;并尽早打印准考证&#xff0c;以免因错过时间而影响考试。…