4G_module/custom/local_tts/src/local_tts.c

244 lines
8.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdio.h"
#include "stdlib.h"
#include "cm_fs.h"
#include "cm_mem.h"
#include "cm_sys.h"
#include "cm_gpio.h"
#include "cm_iomux.h"
#include "cm_modem.h"
#include "cm_audio_player.h"
#include "cm_audio_recorder.h"
#include "cm_local_tts.h"
#include "local_tts.h"
#if 0
#include "app_uart.h"
#define DEBUG(fmt, args...) app_printf("[tts]" fmt, ##args)
#else
#include "app_uart.h"
#define DEBUG(fmt, ...)
#endif
static osMessageQueueId_t local_tts_play_queue = NULL;
// static osMessageQueueId_t local_tts_free_sem_queue = NULL;
static osSemaphoreId_t local_tts_play_ok_sem = NULL;
static osSemaphoreId_t local_tts_play_stat_sem = NULL;
// static int32_t TTS_play_finish_flag = 0; //播放完成标志位 0-完成 !=0-未完成
typedef struct{
cm_local_tts_cfg_t tts_cfg;
uint8_t en_interruptible;
char *text;
uint8_t len;
}tts_play_queue_t;
// 静音 mute: 0-关闭 1-打开
void local_tts_mute(uint8_t mute){
cm_gpio_set_level(CM_GPIO_NUM_13, mute? 1 : 0);
}
// 音量设置 volume: 0-100
uint8_t local_tts_volume(uint8_t volume){
uint8_t ret;
int32_t vol = volume;
if(vol > 100){
vol = 100;
}
// DEBUG("[AUDIO] volume1:%d\n", vol);
cm_audio_play_set_cfg(CM_AUDIO_PLAY_CFG_VOLUME, &vol); //音量设置 0-100
cm_audio_play_get_cfg(CM_AUDIO_PLAY_CFG_VOLUME, &ret);
DEBUG("[AUDIO] volume:%d\n", ret);
return ret;
}
// speed: 语速取值范围0-15默认为5
// volume: 音量取值范围0-15默认为5
// mode: 0-自动模式 1-数字模式,2-数值模式
void local_tts_set(int32_t speed, int32_t volume, cm_local_tts_digit_e mode){
tts_play_queue_t tts_play_queue = {0};
tts_play_queue.text = NULL;
tts_play_queue.len = 1;
tts_play_queue.tts_cfg.speed = speed;
tts_play_queue.tts_cfg.volume = volume;
tts_play_queue.tts_cfg.encode = CM_LOCAL_TTS_ENCODE_TYPE_UTF8; // 离线TTS仅支持UTF8格式
tts_play_queue.tts_cfg.digit = mode;
// DEBUG("tts set:speed %d,volume %d,encode %d,digit %d\n" , tts_play_queue.tts_cfg.speed, tts_play_queue.tts_cfg.volume, tts_play_queue.tts_cfg.encode, tts_play_queue.tts_cfg.digit);
if(osOK != osMessageQueuePut(local_tts_play_queue, &tts_play_queue, 0, 0)){
DEBUG("tts play queue put error\n");
}
// cm_local_tts_deinit();
// cm_local_tts_cfg_t tts_cfg = {0};
// tts_cfg.speed = speed;
// tts_cfg.volume = volume;
// tts_cfg.encode = CM_LOCAL_TTS_ENCODE_TYPE_UTF8; // 离线TTS仅支持UTF8格式
// tts_cfg.digit = mode;
// if(0 == cm_local_tts_init(&tts_cfg)){
// DEBUG("tts set:speed %d,volume %d,encode %d,digit %d\n" , tts_cfg.speed, tts_cfg.volume, tts_cfg.encode, tts_cfg.digit);
// }else{
// DEBUG("tts set error\n");
// }
// osDelay(100/5); // 等待初始化完成
}
// 发送本地TTS播放内容
// len=0时自动计算长度//interruptible =1时,表示允许被打断播放
int8_t local_tts_text_play(char *text, uint8_t len, uint8_t en_interruptible){
// return 0;
DEBUG("tts text:%s,len:%d,en_interruptible:%d \n", text, len, en_interruptible);
tts_play_queue_t tts_play_queue = {0};
local_tts_mute(0); // 取消静音
if(0 == len || len > strlen(text)){
len = strlen(text);
DEBUG("tts text: len > len:%d \n", len);
}
tts_play_queue.text = cm_malloc(len + 1);
if(tts_play_queue.text == NULL){
DEBUG("tts text: malloc error\n");
return -1;
}
memcpy(tts_play_queue.text, text, len);
tts_play_queue.text[len] = '\0';
tts_play_queue.len = len;
tts_play_queue.en_interruptible = en_interruptible;
DEBUG("tts text:Put queue\n");
if(local_tts_play_queue == NULL){
DEBUG("local_tts_play_queue is null\n");
cm_free(tts_play_queue.text);
return -1;
}
if(osOK != osMessageQueuePut(local_tts_play_queue, &tts_play_queue, 0, 0)){
DEBUG("tts text: queue put error\n");
cm_free(tts_play_queue.text);
return -1;
}
return 0;
}
/* 离线TTS回调函数 */
static void __local_tts_callback(cm_local_tts_event_e event, void *param)
{
switch(event){
case CM_LOCAL_TTS_EVENT_SYNTH_DATA:{
// cm_local_tts_synth_data_t *data = (cm_local_tts_synth_data_t *)param;
// DEBUG("[%s] SYNTH_DATA [%d] \n", data->user, data->len); //打印log操作较费时
break;
}
case CM_LOCAL_TTS_EVENT_SYNTH_FAIL:
case CM_LOCAL_TTS_EVENT_SYNTH_INTERRUPT:
case CM_LOCAL_TTS_EVENT_SYNTH_FINISH:
break;
case CM_LOCAL_TTS_EVENT_PLAY_FAIL:
DEBUG("[%s] PLAY_FAIL\n", (char *)param);
break;
case CM_LOCAL_TTS_EVENT_PLAY_INTERRUPT:
DEBUG("[[%s] PLAY_INTERRUPT\n", (char *)param);
// break;
case CM_LOCAL_TTS_EVENT_PLAY_FINISH:{
DEBUG("[PLAY_FINISH] %p=%x \n\n", param, *((osSemaphoreId_t *)param));
osSemaphoreRelease(local_tts_play_ok_sem); // 释放发送成功应答信号量
osSemaphoreRelease(local_tts_play_stat_sem);
break;
}
default:
break;
}
}
// 异步播放,播放完成后播放下一条 //TODO: 待优化(暂时方案,打断播放)
static osThreadFunc_t local_tts_play_task(void *arg){
tts_play_queue_t tts_play_queue;
osStatus_t ret=0;
while(1){
if(osOK == osMessageQueueGet(local_tts_play_queue, &tts_play_queue, NULL, osWaitForever)){ //
if(tts_play_queue.text == NULL){
if(tts_play_queue.len == 1){// 设置TTS参数
tts_play_queue.len = 0;
cm_local_tts_deinit();
if(15 < tts_play_queue.tts_cfg.speed){tts_play_queue.tts_cfg.speed = 15;}
if(15 < tts_play_queue.tts_cfg.volume){tts_play_queue.tts_cfg.volume = 15;}
if(0 == cm_local_tts_init(&tts_play_queue.tts_cfg)){
DEBUG("TASK:speed %d,volume %d,encode %d,digit %d\n", tts_play_queue.tts_cfg.speed, tts_play_queue.tts_cfg.volume, tts_play_queue.tts_cfg.encode, tts_play_queue.tts_cfg.digit);
}else{
DEBUG("tts set error\n");
}
}
DEBUG("tts task: text= null\n");
continue;
}
if(0 == cm_local_tts_play_status()){ // 正在播放中
cm_local_tts_play_stop();// 停止播放
ret =osSemaphoreAcquire(local_tts_play_stat_sem, 30000/5);// 等待播放结束
if(osOK != ret){
DEBUG("local_tts_play_stat_sem:%d\n", ret);
}
}
// DEBUG("tts task: 00000000000\n\n");
cm_local_tts_play(tts_play_queue.text, tts_play_queue.len, __local_tts_callback, NULL);
// DEBUG("tts task: 1111111111\n\n");
// if(0 == tts_play_queue.en_interruptible){ // 不允许被打断播放
// DEBUG("tts task: 2222222222\n\n");
ret =osSemaphoreAcquire(local_tts_play_ok_sem, (0 == tts_play_queue.en_interruptible)?(30000/5):(2000/5));// 等待播放结束
if(osOK != ret){
DEBUG("local_tts_play_ok_sem:%d\n", ret);
}
// }else{
// osSemaphoreAcquire(local_tts_play_ok_sem, 300/5);
// }
// DEBUG("tts task: 3333333333\n\n");
cm_free(tts_play_queue.text);
tts_play_queue.text = NULL;
}
}
return 0;
}
// 初始化
void local_tts_init(void){
cm_gpio_cfg_t cfg = {0};
cfg.direction = CM_GPIO_DIRECTION_OUTPUT;
cfg.pull = CM_GPIO_PULL_UP;
cm_iomux_set_pin_func(CM_IOMUX_PIN_77, CM_IOMUX_FUNC_FUNCTION2);//初始化之前一定要先设置引脚复用
cm_gpio_init(CM_GPIO_NUM_13, &cfg);
local_tts_mute(1); // 开启静音
local_tts_volume(100); // 设置音量为50
cm_local_tts_deinit();
cm_local_tts_cfg_t tts_cfg={
.speed = 6,
.volume = 7,
.encode = CM_LOCAL_TTS_ENCODE_TYPE_UTF8, // 离线TTS仅支持UTF8格式
.digit = CM_LOCAL_TTS_DIGIT_AUTO, // 自动模式
};
if(0 == cm_local_tts_init(&tts_cfg)){
DEBUG("local_tts_init:speed %d,volume %d,encode %d,digit %d\n", tts_cfg.speed, tts_cfg.volume, tts_cfg.encode, tts_cfg.digit);
}else{
DEBUG("local_tts_init error\n");
}
if(local_tts_play_queue == NULL){
local_tts_play_queue = osMessageQueueNew(50, sizeof(tts_play_queue_t), NULL);
}
if(local_tts_play_ok_sem == NULL){
local_tts_play_ok_sem = osSemaphoreNew(1, 0, NULL);
}
if(local_tts_play_stat_sem == NULL){
local_tts_play_stat_sem = osSemaphoreNew(1, 0, NULL);
}
osThreadAttr_t local_tts_play_thread_attr = {
.name = "local_tts_play_thread",
.stack_size = 4096*4,
.priority = osPriorityNormal
};
osThreadNew((osThreadFunc_t)local_tts_play_task, NULL, &local_tts_play_thread_attr);
}