244 lines
8.0 KiB
C
244 lines
8.0 KiB
C
#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);
|
||
}
|