作者 ookk303

讯飞2代库优化

#include <fstream>
#include <assert.h>
#include <cstring>
#include <atomic>
#include <unistd.h>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include "JZsdkLib.h"
#include "version_choose.h"
#include "JZsdk_base/JZring/JZring.h"
#if 1
#include "aikit_biz_api.h"
#include "aikit_constant.h"
#include "aikit_biz_config.h"
#include "iflytek_tts.h"
#include "AudioDeal/AudioDeal.h"
#include "../../Megaphone.h"
#include "iflytek_tts.h"
using namespace std;
using namespace AIKIT;
static std::atomic_bool ttsFinished(false);
static std::atomic_bool g_playThreadRunning(false);
static const char *ABILITY = "e2e44feff";
static AIKIT_HANDLE *g_AikitHandle = nullptr; // 合成句柄
static int IflytekLib_2_StopTts();
#define IFLYTEK_RING_BUF_SIZE (1024 * 100) // 100KB缓冲区
static T_JZringHandle g_ringHandle = nullptr;
static char *g_ringBuf = nullptr;
// 同步机制
static std::mutex g_mutex;
static std::condition_variable g_cv;
// 播放线程函数
void PlaybackThreadFunc()
{
U8_t buffer[2048]; // 每次读取2KB
U32_t readSize = 0;
T_JZsdkReturnCode ret;
g_playThreadRunning = true;
while (g_playThreadRunning)
{
// 等待有数据可读
{
std::unique_lock<std::mutex> lock(g_mutex);
U32_t dataCount = 0;
JZring_GetDataCount(g_ringHandle, &dataCount);
if (dataCount == 0) {
// 等待最多100ms或通知
g_cv.wait_for(lock, std::chrono::milliseconds(100));
continue;
}
}
JZSDK_LOG_DEBUG("有数据可读");
// 从环形缓冲区读取数据
ret = JZring_Read(g_ringHandle, buffer, sizeof(buffer), &readSize);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS || readSize == 0) {
usleep(10000); // 10ms
continue;
}
// 发送到音频播放器
AudioDeal_PcmDataInput_TextSteam(16000, buffer, readSize);
// 检查是否需要停止播放
if (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_OFF) {
break;
}
}
g_playThreadRunning = false;
}
void OnOutput(AIKIT_HANDLE* handle, const AIKIT_OutputData* output)
{
// 检测数据生成标志位是否有关闭
if (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_OFF) {
IflytekLib_2_StopTts();
return;
}
if (output->node->value) {
JZSDK_LOG_DEBUG("生产了数据%d", output->node->len);
// 写入环形缓冲区
T_JZsdkReturnCode ret;
U32_t written = 0;
while (written < static_cast<U32_t>(output->node->len)) {
U32_t chunkSize = std::min(static_cast<U32_t>(output->node->len) - written,
static_cast<U32_t>(4096));
ret = JZring_Write(g_ringHandle,
reinterpret_cast<U8_t*>(output->node->value) + written,
chunkSize);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
JZSDK_LOG_ERROR("写入环形缓冲区失败: %d", ret);
break;
}
written += chunkSize;
}
// 通知播放线程有新数据
g_cv.notify_one();
}
}
void OnEvent(AIKIT_HANDLE* handle, AIKIT_EVENT eventType, const AIKIT_OutputEvent* eventValue) {
if (eventType == AIKIT_Event_End) {
ttsFinished = true;
JZSDK_LOG_INFO("合成完成");
// 通知播放线程所有数据已生成
g_cv.notify_one();
}
}
void OnError(AIKIT_HANDLE* handle, int32_t err, const char* desc) {
JZSDK_LOG_ERROR("TTS错误: %d, %s", err, desc);
IflytekLib_2_StopTts();
}
int IflytekLib_2_TextToTts(int language,
const char *TtsRole,
const char *text, int speed, int volume)
{
AIKIT_ParamBuilder* paramBuilder = nullptr;
AIKIT_DataBuilder* dataBuilder = nullptr;
AiText* aiText_raw = nullptr;
int ret = 0;
// 重置完成标志
ttsFinished = false;
// 重置环形缓冲区
JZring_Reset(g_ringHandle);
paramBuilder = AIKIT_ParamBuilder::create();
paramBuilder->clear();
// 设置发音人
paramBuilder->param("vcn", TtsRole, strlen(TtsRole));
paramBuilder->param("vcnModel", TtsRole, strlen(TtsRole));
// 设置语种
paramBuilder->param("language", language);
// 设置文本编码
paramBuilder->param("textEncoding", "UTF-8", strlen("UTF-8"));
// 音量
paramBuilder->param("volume", volume);
// 语速
paramBuilder->param("speed", speed);
JZSDK_LOG_DEBUG("TTS Role:%s, Text:%s, language:%d", TtsRole, text, language);
ret = AIKIT_Start(ABILITY, AIKIT_Builder::build(paramBuilder), nullptr, &g_AikitHandle);
if(ret != 0) {
JZSDK_LOG_ERROR("AIKIT_Start failed: %d", ret);
goto exit;
}
dataBuilder = AIKIT_DataBuilder::create();
dataBuilder->clear();
aiText_raw = AiText::get("text")->data(text, strlen(text))->once()->valid();
dataBuilder->payload(aiText_raw);
ret = AIKIT_Write(g_AikitHandle, AIKIT_Builder::build(dataBuilder));
if(ret != 0) {
JZSDK_LOG_ERROR("AIKIT_Write failed: %d", ret);
goto exit;
}
// 等待合成完成或停止信号
while(!ttsFinished) {
if (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_OFF) {
break;
}
usleep(10000); // 10ms
}
// 结束合成
ret = AIKIT_End(g_AikitHandle);
g_AikitHandle = nullptr;
exit:
if(paramBuilder != nullptr) {
delete paramBuilder;
}
if(dataBuilder != nullptr) {
delete dataBuilder;
}
return ret;
}
int IflytekLib_2_Init()
{
// 初始化环形缓冲区
g_ringBuf = new char[IFLYTEK_RING_BUF_SIZE];
if (JZring_Init(&g_ringHandle, reinterpret_cast<U8_t*>(g_ringBuf), IFLYTEK_RING_BUF_SIZE)
!= JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
JZSDK_LOG_ERROR("环形缓冲区初始化失败");
return -1;
}
// 启动播放线程
std::thread(PlaybackThreadFunc).detach();
// 初始化TTS SDK
AIKIT_Configurator::builder()
.app()
.appID("03857dfd")
.apiSecret("OTA2OTEzMTVlOGYwMjllMmJkYzEwZGY5")
.apiKey("2b2c60f8a80b8cdfe45ae1058a25149a")
.workDir("/root/Iflytek_2")
.auth()
.authType(0)
.log()
.logLevel(LOG_LVL_OFF) //关闭日志打印
.logMode(LOG_STDOUT); //日志输出为控制台
int ret = AIKIT_Init();
if(ret != 0) {
JZSDK_LOG_ERROR("AIKIT_Init failed: %d", ret);
return -1;
}
AIKIT_Callbacks cbs = {OnOutput, OnEvent, OnError};
AIKIT_RegisterAbilityCallback(ABILITY, cbs);
return 0;
}
int IflytekLib_2_UnInit()
{
// 停止播放线程
g_playThreadRunning = false;
g_cv.notify_one();
// 等待播放线程退出
int waitCount = 0;
while (g_playThreadRunning && waitCount++ < 50) {
usleep(100000); // 100ms
}
// 反初始化TTS SDK
if (g_AikitHandle) {
AIKIT_End(g_AikitHandle);
g_AikitHandle = nullptr;
}
AIKIT_UnInit();
// 释放环形缓冲区
if (g_ringHandle) {
JZring_DeInit(g_ringHandle);
g_ringHandle = nullptr;
}
if (g_ringBuf) {
delete[] g_ringBuf;
g_ringBuf = nullptr;
}
return 0;
}
static int IflytekLib_2_StopTts()
{
if (g_AikitHandle) {
AIKIT_End(g_AikitHandle);
g_AikitHandle = nullptr;
ttsFinished = true;
JZSDK_LOG_INFO("TTS合成已停止");
}
// 通知播放线程
g_cv.notify_one();
return 0;
}
#endif
\ No newline at end of file
// #include <fstream>
// #include <assert.h>
// #include <cstring>
// #include <atomic>
// #include <unistd.h>
// #include <string>
// #include "JZsdkLib.h"
// #include "version_choose.h"
// #include "JZsdk_base/JZring/JZring.h"
// #ifdef IFLAY_TTS_2_CONFIG_STATUS_ON
// #include "aikit_biz_api.h"
// #include "aikit_constant.h"
// #include "aikit_biz_config.h"
// #include "iflytek_tts.h"
// #include "AudioDeal/AudioDeal.h"
// #include "../../Megaphone.h"
// #include "iflytek_tts.h"
// using namespace std;
// using namespace AIKIT;
// static std::atomic_bool ttsFinished(false);
// static const char *ABILITY = "e2e44feff";
// static AIKIT_HANDLE *g_AikitHandle = nullptr; //合成句柄
// static int IflytekLib_2_StopTts();
// static FILE *iflytts_fp = NULL;
// #define IFLYTTS_FP_NAME "/root/tmp_tts_file.pcm"
// void OnOutput(AIKIT_HANDLE* handle, const AIKIT_OutputData* output)
// {
// //检测数据生成标志位是否有关闭,如果有关闭,则主动关闭合成,并退出该事件
// if (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_OFF)
// {
// IflytekLib_2_StopTts();
// return;
// }
// //如果存在数据,则播放
// if (output->node->value)
// {
// //生产的文本数据 output->node->value
// //生产的数据长度 output->node->len
// //char类型
// //JZSDK_LOG_DEBUG("生产了数据%d", output->node->len);
// printf("生产了数据%d\n", output->node->len);
// //将该数据发送到alsa播放器
// //AudioDeal_PcmDataInput_TextSteam(16000, (unsigned char *)output->node->value, output->node->len);
// if (iflytts_fp != NULL)
// {
// fwrite(output->node->value, sizeof(char), output->node->len, iflytts_fp);
// fflush(iflytts_fp);
// }
// }
// }
// void OnEvent(AIKIT_HANDLE* handle, AIKIT_EVENT eventType, const AIKIT_OutputEvent* eventValue) {
// if (eventType == AIKIT_Event_End) {
// ttsFinished = true;
// JZSDK_LOG_INFO("合成完成");
// }
// }
// void OnError(AIKIT_HANDLE* handle, int32_t err, const char* desc) {
// printf("OnError:%d\n", err);
// //报错
// }
// int IflytekLib_2_TextToTts(int language,
// const char *TtsRole,
// const char *text, int speed, int volume)
// {
// if (iflytts_fp != NULL)
// {
// JZSDK_LOG_ERROR("file %s is not closed\n", IFLYTTS_FP_NAME);
// return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
// }
// AIKIT_ParamBuilder* paramBuilder = nullptr;
// AIKIT_DataBuilder* dataBuilder = nullptr;
// AiText* aiText_raw = nullptr;
// // 重置完成标志
// ttsFinished = false;
// paramBuilder = AIKIT_ParamBuilder::create();
// paramBuilder->clear();
// // 设置发音人
// paramBuilder->param("vcn", TtsRole, strlen(TtsRole));
// paramBuilder->param("vcnModel", TtsRole, strlen(TtsRole));
// // 设置语种
// paramBuilder->param("language", language);
// // 设置文本编码
// paramBuilder->param("textEncoding", "UTF-8", strlen("UTF-8"));
// //语速
// paramBuilder->param("speed",speed); //可选参数,默认为0
// //音调
// //paramBuilder->param("pitch",100); //可选参数,默认为0
// //声音
// //paramBuilder->param("volume",100);//可选参数,默认为0
// //打开临存文件
// iflytts_fp = fopen(IFLYTTS_FP_NAME, "w+b");
// if (iflytts_fp == NULL)
// {
// JZSDK_LOG_ERROR("open file %s failed\n", IFLYTTS_FP_NAME);
// return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
// }
// //JZSDK_LOG_DEBUG("TTS Role:%s Len:%d, Text:%s Len:%d, language:%d", TtsRole, strlen(TtsRole), text, strlen(text), language);
// int ret = AIKIT_Start(ABILITY, AIKIT_Builder::build(paramBuilder), nullptr, &g_AikitHandle);
// if(ret != 0) {
// printf("AIKIT_Start failed: %d\n", ret);
// goto exit;
// }
// dataBuilder = AIKIT_DataBuilder::create();
// dataBuilder->clear();
// //aiText_raw = AiText::get("text")->data(text.c_str(), text.length())->once()->valid();
// aiText_raw = AiText::get("text")->data(text, strlen(text) )->once()->valid();
// dataBuilder->payload(aiText_raw);
// ret = AIKIT_Write(g_AikitHandle, AIKIT_Builder::build(dataBuilder));
// if(ret != 0) {
// printf("AIKIT_Write failed: %d\n", ret);
// goto exit;
// }
// // 等待合成完成
// while(!ttsFinished) {
// usleep(1000);
// }
// JZSDK_LOG_DEBUG("合成完成,开始播放");
// //将fp指针移到文件开头
// fseek(iflytts_fp, 0, SEEK_SET);
// //将数据导入播放器
// unsigned char buffer[1024];
// int len;
// while (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) != JZ_FLAGCODE_OFF)
// {
// len = fread(buffer, sizeof(char), 1024, iflytts_fp);
// if (len <= 0)
// {
// JZSDK_LOG_DEBUG("已读取完毕\n");
// break;
// }
// AudioDeal_PcmDataInput_TextSteam(16000, buffer, len);
// }
// JZSDK_LOG_INFO("播放完成");
// ret = AIKIT_End(g_AikitHandle);
// exit:
// if(paramBuilder != nullptr) {
// delete paramBuilder;
// }
// if(dataBuilder != nullptr) {
// delete dataBuilder;
// }
// if (iflytts_fp != NULL)
// {
// fclose(iflytts_fp);
// iflytts_fp = NULL;
// }
// return 0;
// }
// int IflytekLib_2_UnInit()
// {
// AIKIT_UnInit();
// return 0;
// }
// static int IflytekLib_2_StopTts()
// {
// AIKIT_OutputEvent eventData = {};
// if (g_AikitHandle != nullptr)
// {
// OnEvent(g_AikitHandle,AIKIT_Event_End,&eventData);
// }
// return 0;
// }
// #define IFLYTEK_RING_BUF_SIZE (1024 * 100) // 100KB缓冲区
// static T_JZringHandle g_ringHandle = nullptr;
// static char *g_ringBuf = nullptr;
// static int g_AudioPlayFinshFlag = JZ_FLAGCODE_OFF;
// static int g_playThreadRunning = JZ_FLAGCODE_OFF;
// static void PlaybackThreadFunc()
// {
// T_JZsdkOsalHandler *osHandler = JZsdk_Platform_GetOsalHandler;
// U8_t buffer[2048]; // 每次读取2KB
// U32_t readSize = 0;
// T_JZsdkReturnCode ret;
// U32_t dataCount = 0;
// g_playThreadRunning = JZ_FLAGCODE_ON;
// while (g_playThreadRunning == JZ_FLAGCODE_ON)
// {
// //监测缓冲区是否有数据
// dataCount = 0;
// ret = JZring_GetDataCount(g_ringHandle, &dataCount);
// if (dataCount == 0)
// {
// //等候线程唤醒
// continue;
// }
// //读取数据
// ret = JZring_Read(g_ringHandle, buffer, sizeof(buffer), &readSize);
// if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
// {
// JZSDK_LOG_ERROR("读取环形缓冲区失败");
// break;
// }
// //写入音频播放器
// AudioDeal_PcmDataInput_TextSteam(16000, buffer, readSize);
// g_AudioPlayFinshFlag = JZ_FLAGCODE_ON;
// //检查
// }
// }
// T_JZsdkReturnCode IflytekLib_2_Init()
// {
// //初始化环形缓冲区
// g_ringBuf = new char[IFLYTEK_RING_BUF_SIZE];
// if (JZring_Init(&g_ringHandle, reinterpret_cast<U8_t*>(g_ringBuf), IFLYTEK_RING_BUF_SIZE)
// != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
// JZSDK_LOG_ERROR("环形缓冲区初始化失败");
// return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
// }
// T_JZsdkOsalHandler *osHandler = JZsdk_Platform_GetOsalHandler;
// T_JZTaskHandle taskhandle;
// osHandler->TaskCreate("IfytekLibPlay", PlaybackThreadFunc, 1024, NULL, &taskhandle);
// AIKIT_Configurator::builder()
// .app()
// .appID("03857dfd")
// .apiSecret("OTA2OTEzMTVlOGYwMjllMmJkYzEwZGY5")
// .apiKey("2b2c60f8a80b8cdfe45ae1058a25149a")
// .workDir("/root/Iflytek_2")
// .auth()
// .authType(0)
// .log()
// .logLevel(LOG_LVL_OFF) //关闭日志打印
// .logMode(LOG_STDOUT); //日志输出为控制台
// int ret = AIKIT_Init();
// if(ret != 0) {
// printf("AIKIT_Init failed: %d\n", ret);
// return -1;
// }
// AIKIT_Callbacks cbs = {OnOutput, OnEvent, OnError};
// AIKIT_RegisterAbilityCallback(ABILITY, cbs);
// return 0;
// }
// #endif
\ No newline at end of file
... ... @@ -107,8 +107,16 @@ void OnOutput(AIKIT_HANDLE* handle, const AIKIT_OutputData* output)
ret = JZring_Write(g_ringHandle,
reinterpret_cast<U8_t*>(output->node->value) + written,
chunkSize);
if (ret == JZ_ERROR_SYSTEM_MODULE_CODE_BUFFER_SIZE_NOT_ENOUGH)
{
//缓冲区暂无空间,等待一段时间再写入
usleep(10000); // 10ms
continue;
}
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS && ret != JZ_ERROR_SYSTEM_MODULE_CODE_BUFFER_SIZE_NOT_ENOUGH)
{
JZSDK_LOG_ERROR("写入环形缓冲区失败: %d", ret);
break;
}
... ...
#include <fstream>
#include <assert.h>
#include <cstring>
#include <atomic>
#include <unistd.h>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include "JZsdkLib.h"
#include "version_choose.h"
#include "JZsdk_base/JZring/JZring.h"
#if 0
#include "aikit_biz_api.h"
#include "aikit_constant.h"
#include "aikit_biz_config.h"
#include "iflytek_tts.h"
#include "AudioDeal/AudioDeal.h"
#include "../../Megaphone.h"
#include "iflytek_tts.h"
using namespace std;
using namespace AIKIT;
static std::atomic_bool ttsFinished(false);
static std::atomic_bool g_playThreadRunning(false);
static const char *ABILITY = "e2e44feff";
static AIKIT_HANDLE *g_AikitHandle = nullptr; // 合成句柄
static int IflytekLib_2_StopTts();
#define IFLYTEK_RING_BUF_SIZE (1024 * 100) // 100KB缓冲区
static T_JZringHandle g_ringHandle = nullptr;
static char *g_ringBuf = nullptr;
static int g_AudioPlayFinshFlag = JZ_FLAGCODE_OFF;
// 同步机制
static std::mutex g_mutex;
static std::condition_variable g_cv;
// 播放线程函数
void PlaybackThreadFunc()
{
U8_t buffer[2048]; // 每次读取2KB
U32_t readSize = 0;
T_JZsdkReturnCode ret;
g_playThreadRunning = true;
std::unique_lock<std::mutex> lock(g_mutex);
while (g_playThreadRunning)
{
// 等待有数据可读
{
U32_t dataCount = 0;
JZring_GetDataCount(g_ringHandle, &dataCount);
JZSDK_LOG_DEBUG("缓冲区数据量: %d", dataCount);
if (dataCount == 0) {
// 等待最多100ms或通知
g_cv.wait_for(lock, std::chrono::milliseconds(100));
continue;
}
}
g_AudioPlayFinshFlag = JZ_FLAGCODE_ON;
JZSDK_LOG_DEBUG("有数据可读");
// 从环形缓冲区读取数据
ret = JZring_Read(g_ringHandle, buffer, sizeof(buffer), &readSize);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS || readSize == 0) {
usleep(10000); // 10ms
continue;
}
JZSDK_LOG_DEBUG("输入数据进音频库");
// 发送到音频播放器
AudioDeal_PcmDataInput_TextSteam(16000, buffer, readSize);
g_AudioPlayFinshFlag = JZ_FLAGCODE_OFF;
JZSDK_LOG_DEBUG("音频库播放完毕");
// 检查是否需要停止播放
if (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_OFF) {
break;
}
}
g_playThreadRunning = false;
}
void OnOutput(AIKIT_HANDLE* handle, const AIKIT_OutputData* output)
{
// 检测数据生成标志位是否有关闭
if (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_OFF) {
IflytekLib_2_StopTts();
return;
}
if (output->node->value) {
JZSDK_LOG_DEBUG("生产了数据%d", output->node->len);
// 写入环形缓冲区
T_JZsdkReturnCode ret;
U32_t written = 0;
while (written < static_cast<U32_t>(output->node->len)) {
U32_t chunkSize = std::min(static_cast<U32_t>(output->node->len) - written,
static_cast<U32_t>(4096));
ret = JZring_Write(g_ringHandle,
reinterpret_cast<U8_t*>(output->node->value) + written,
chunkSize);
if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
JZSDK_LOG_ERROR("写入环形缓冲区失败: %d", ret);
break;
}
written += chunkSize;
}
// 通知播放线程有新数据
g_cv.notify_one();
}
}
void OnEvent(AIKIT_HANDLE* handle, AIKIT_EVENT eventType, const AIKIT_OutputEvent* eventValue) {
if (eventType == AIKIT_Event_End) {
ttsFinished = true;
JZSDK_LOG_INFO("合成完成");
// 通知播放线程所有数据已生成
g_cv.notify_one();
}
}
void OnError(AIKIT_HANDLE* handle, int32_t err, const char* desc) {
JZSDK_LOG_ERROR("TTS错误: %d, %s", err, desc);
IflytekLib_2_StopTts();
}
int IflytekLib_2_TextToTts(int language,
const char *TtsRole,
const char *text, int speed, int volume)
{
AIKIT_ParamBuilder* paramBuilder = nullptr;
AIKIT_DataBuilder* dataBuilder = nullptr;
AiText* aiText_raw = nullptr;
int ret = 0;
// 重置完成标志
ttsFinished = false;
// 重置环形缓冲区
JZring_Reset(g_ringHandle);
paramBuilder = AIKIT_ParamBuilder::create();
paramBuilder->clear();
// 设置发音人
paramBuilder->param("vcn", TtsRole, strlen(TtsRole));
paramBuilder->param("vcnModel", TtsRole, strlen(TtsRole));
// 设置语种
paramBuilder->param("language", language);
// 设置文本编码
paramBuilder->param("textEncoding", "UTF-8", strlen("UTF-8"));
// 音量
paramBuilder->param("volume", volume);
// 语速
paramBuilder->param("speed", speed);
JZSDK_LOG_DEBUG("TTS Role:%s, Text:%s, language:%d", TtsRole, text, language);
ret = AIKIT_Start(ABILITY, AIKIT_Builder::build(paramBuilder), nullptr, &g_AikitHandle);
if(ret != 0) {
JZSDK_LOG_ERROR("AIKIT_Start failed: %d", ret);
goto exit;
}
dataBuilder = AIKIT_DataBuilder::create();
dataBuilder->clear();
aiText_raw = AiText::get("text")->data(text, strlen(text))->once()->valid();
dataBuilder->payload(aiText_raw);
ret = AIKIT_Write(g_AikitHandle, AIKIT_Builder::build(dataBuilder));
if(ret != 0) {
JZSDK_LOG_ERROR("AIKIT_Write failed: %d", ret);
goto exit;
}
// 等待合成完成或停止信号
while(!ttsFinished || g_AudioPlayFinshFlag == JZ_FLAGCODE_ON) {
if (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_OFF) {
break;
}
usleep(10000); // 10ms
}
JZSDK_LOG_INFO("合成结束");
// 结束合成
ret = AIKIT_End(g_AikitHandle);
g_AikitHandle = nullptr;
exit:
if(paramBuilder != nullptr) {
delete paramBuilder;
}
if(dataBuilder != nullptr) {
delete dataBuilder;
}
return ret;
}
int IflytekLib_2_Init()
{
// 初始化环形缓冲区
g_ringBuf = new char[IFLYTEK_RING_BUF_SIZE];
if (JZring_Init(&g_ringHandle, reinterpret_cast<U8_t*>(g_ringBuf), IFLYTEK_RING_BUF_SIZE)
!= JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
JZSDK_LOG_ERROR("环形缓冲区初始化失败");
return -1;
}
// 启动播放线程
std::thread(PlaybackThreadFunc).detach();
// 初始化TTS SDK
AIKIT_Configurator::builder()
.app()
.appID("03857dfd")
.apiSecret("OTA2OTEzMTVlOGYwMjllMmJkYzEwZGY5")
.apiKey("2b2c60f8a80b8cdfe45ae1058a25149a")
.workDir("/root/Iflytek_2")
.auth()
.authType(0)
.log()
.logLevel(LOG_LVL_OFF) //关闭日志打印
.logMode(LOG_STDOUT); //日志输出为控制台
int ret = AIKIT_Init();
if(ret != 0) {
JZSDK_LOG_ERROR("AIKIT_Init failed: %d", ret);
return -1;
}
AIKIT_Callbacks cbs = {OnOutput, OnEvent, OnError};
AIKIT_RegisterAbilityCallback(ABILITY, cbs);
return 0;
}
int IflytekLib_2_UnInit()
{
// 停止播放线程
g_playThreadRunning = false;
g_cv.notify_one();
// 等待播放线程退出
int waitCount = 0;
while (g_playThreadRunning && waitCount++ < 50) {
usleep(100000); // 100ms
}
// 反初始化TTS SDK
if (g_AikitHandle) {
AIKIT_End(g_AikitHandle);
g_AikitHandle = nullptr;
}
AIKIT_UnInit();
// 释放环形缓冲区
if (g_ringHandle) {
JZring_DeInit(g_ringHandle);
g_ringHandle = nullptr;
}
if (g_ringBuf) {
delete[] g_ringBuf;
g_ringBuf = nullptr;
}
return 0;
}
static int IflytekLib_2_StopTts()
{
if (g_AikitHandle) {
AIKIT_End(g_AikitHandle);
g_AikitHandle = nullptr;
ttsFinished = true;
JZSDK_LOG_INFO("TTS合成已停止");
}
// 通知播放线程
g_cv.notify_one();
return 0;
}
#endif
\ No newline at end of file