科大讯飞离线lunix tts demo使用

news/2024/11/6 17:18:50/文章来源:https://www.cnblogs.com/rolayblog/p/18530577

项目中需要用到后台服务端用文本生成语音,网上大部分都是通过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.hqwc.cn/news/827745.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高效数据集成:从旺店通到金蝶云

旺店通旗舰奇门数据集成到金蝶云星空:柏为销售出库单07.25 在现代企业的运营中,数据的高效流转和准确对接是确保业务顺畅运行的关键。本文将分享一个实际案例——如何通过轻易云数据集成平台,将旺店通旗舰奇门的数据无缝集成到金蝶云星空系统中。具体方案名称为“柏为销售出…

对比山海鲸报表和Tableau,哪款报表软件更好用?

在数据分析和报表制作的领域,企业往往面临着选择合适工具的难题。尤其是当市场上有很多功能强大的工具时,如何从中挑选出最适合自己需求的报表软件成为了一个关键问题。今天,我们将对比两款报表工具——山海鲸报表和Tableau,看看它们各自的特点和优势,帮助你做出明智的选择…

团子东子开奖了,这泼天的富贵!

秋招已经接近尾声了,最近各家公司的薪资也陆续公布了,今天在逛某客时,被一个 25 届 C9 硕的薪资羡慕到了,一起来感受下这泼天的富贵吧。 这个同学今年秋招总共拿到了 3 个 Offer,分别是:小米:28K*15,总包 45W,sp,北京。 美团:30K*15.5,总包 47W,sp,上海。 京东:…

odoo中对多条数据按条件进行分类汇总 read_group的用法总结并抽取出公式

今天在工作中遇到一个这样的问题。要求:做一个打印模板实现下面图中的分类汇总 py3o://for="o in object.delivery_containers_line.read_group(domain=[(delivery_order_id,=,object.id)], fields=[customer_id, delivery_order_id, sales_order_id, supplier_id,purcha…

百万年薪!2024 Salesforce高薪职位排行

随着Salesforce在全球的普及,这一平台不仅带来了新的职场机会,更为从业者提供了优渥的薪资待遇。 最近的Salesforce薪资调查显示,Salesforce生态系统中不同职位的薪资水平相当可观,尤其在美国市场,一些顶级岗位的年薪可达到令人惊叹的百万级别。今天我们就来细数2024年Sal…

初识AI大模型,ollama使用,llama factory大模型微调,lama.cpp模型转换guff

最近了解了下生成式AI对话,下面是自己的一些尝试记录。ollama 安装及使用1、安装我是在windows环境下安装的,很简单,访问:https://ollama.com/ ,下载windows安装包,打开安装就行了。cmd输入ollama -v检验是否安装成功。2、配置在环境变量的用户变量中加入如下几个:   …

zlibrary中文版入口及电子书客户端/app(2024更新)

Z-library是一个全球范围内庞大的数字图书馆之一,其藏书量非常丰富。截至最新数据,Z-library共收录了超过9,826,996册电子书以及84,837,646篇学术期刊文章。这个数字图书馆覆盖了从经典文学巨著到前沿理工学科,从人文艺术瑰宝到专业学术论文的广泛领域,几乎能够满足每一位求…

Playwright:掌握Web自动化测试的新利器

在快速迭代的互联网环境中,Web应用的测试工作日益繁重。传统的手动测试不仅耗时耗力,还难以保证测试的全面性和准确性。面对复杂多变的测试需求,你是否也曾感到力不从心? 别担心!本周四晚上八点,我们特别策划了一场关于Playwright的公开课,旨在帮助大家掌握这款Web自动化…

NOIP2024加赛2

NOIP2024加赛2 题目来源: 2023NOIP A层联测18\(T1\) HZTG5733. 新的阶乘 \(100pts\)预处理素数后直接对 \(1 \sim n\) 进行质因数分解因为有太多冗余枚举导致无法通过。考虑枚举最终形式。具体地,从质因数的角度入手,设当前枚举的质数为 \(p\) ,暴力求出 \(ip\) 中 \(p\) 的…

用处多多!信创PostgreSQL认证证书含金量

PostgreSQL是目前讨论比较多的数据库技术,国内很多大的企业都在开发基于PostgreSQL的数据库产品,比如腾讯云TDSQL-PG版、阿里云PolarDB-PG版、人大金仓等等,考取PostgreSQL数据库证书对个人在数据库领域的职业发展具有多方面的积极作用。以下是对其用处的详细分析: ​ 一、…

南沙C++信奥赛陈老师解一本通题 1225:金银岛

​【题目描述】某天KID利用飞行器飞到了一个金银岛上,上面有许多珍贵的金属,KID虽然更喜欢各种宝石的艺术品,可是也不拒绝这样珍贵的金属。但是他只带着一个口袋,口袋至多只能装重量为w的物品。岛上金属有ss个种类, 每种金属重量不同,分别为n1,n2,...,nsn1,n2,...,ns,同时…

精准、智能、高效:AI平台如何提升医疗数据处理效率50%

思通数科的大模型是一款集成自然语言处理、多模态分析与知识图谱技术的智能系统,专为提升行业信息处理效率和决策支持而设计。该模型依托深度学习与数据驱动,能够在合同审查、智能问答、医疗文本处理等场景中实现精准的文本分类、信息抽取与风险识别。特别在多模态数据处理方…