#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 1 #include "app_uart.h" #define DEBUG(fmt, args...) app_printf("[tts]" fmt, ##args) #else #define DEBUG(fmt, arg...) #endif static osMessageQueueId_t local_tts_play_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; 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; if(volume > 100){ volume = 100; } cm_audio_play_set_cfg(CM_AUDIO_PLAY_CFG_VOLUME, &volume); //音量设置 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播放内容 //timeout=osWaitForever时表示等待播放完成 //len=0时自动计算长度 // en_break=1时使能打断播放 //timeout=0时表示播放忙时,取消播放 int8_t local_tts_text_play(char *text, uint8_t len, uint8_t en_break, uint32_t timeout){ DEBUG("tts play text:%s,len:%d,en_break:%d,timeout:%d\n", text, len, en_break, timeout); // if((en_break == 0) && (TTS_play_finish_flag != 0)){ // if(TTS_play_finish_flag < 0){ // TTS_play_finish_flag = 0; // } // DEBUG("tts play busy\n"); // return -1; // } // if((en_break == 1)||(TTS_play_finish_flag < 0)){// 使能打断播放 // TTS_play_finish_flag = 0; // } if((en_break == 1) && (TTS_play_finish_flag != 0)){ cm_local_tts_play_stop(); // 停止播放 while(TTS_play_finish_flag==0){//等待转码结束 osDelay(50/5); // 等待播放停止 } // osSemaphoreAcquire(local_tts_play_stat_sem, 300/5);// 等待播放结束 } tts_play_queue_t tts_play_queue = {0}; local_tts_mute(0); // 取消静音 if(0 == len || len > strlen(text)){ len = strlen(text); DEBUG("tts play text len > len:%d \n", len); } tts_play_queue.text = cm_malloc(len + 1); if(tts_play_queue.text == NULL){ DEBUG("tts play malloc error\n"); return -1; } memcpy(tts_play_queue.text, text, len); tts_play_queue.text[len] = '\0'; tts_play_queue.len = len; if(osOK != osMessageQueuePut(local_tts_play_queue, &tts_play_queue, 0, 0)){ DEBUG("tts play queue put error\n"); cm_free(tts_play_queue.text); return -1; } TTS_play_finish_flag =1; //播放完成标志位 0-完成 !=0-未完成 // 等待播放完成 osSemaphoreAcquire(local_tts_play_ok_sem, timeout); DEBUG("tts play queue put success\n"); 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("[%s] PLAY_FINISH\n", (char *)param); // TTS_play_finish_flag =0; //播放完成标志位 0-完成 !=0-未完成 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)){ // // cm_local_tts_play_stop(); // 停止播放 // osDelay(300/5); // 等待播放停止 if(tts_play_queue.text == NULL){ if(tts_play_queue.len != 0){ 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"); } osDelay(200/5); } DEBUG("tts play text is null\n"); continue; } DEBUG("tts play start\n"); // TTS_play_finish_flag =1; //播放完成标志位 0-完成 !=0-未完成 cm_local_tts_play(tts_play_queue.text, tts_play_queue.len, __local_tts_callback, "Chinese"); TTS_play_finish_flag =2; //播放完成标志位 0-完成 !=0-未完成 ret =osSemaphoreAcquire(local_tts_play_stat_sem, 60000/5);// 等待播放结束 if(osOK != ret){ DEBUG("tts play queue stat error:%d\n", ret); } TTS_play_finish_flag =0; //播放完成标志位 0-完成 !=0-未完成 DEBUG("tts play stop\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 = 5, .volume = 15, .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"); } osDelay(200/5); // 等待初始化完成 if(local_tts_play_queue == NULL){ local_tts_play_queue = osMessageQueueNew(1, 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, .priority = osPriorityNormal }; osThreadNew((osThreadFunc_t)local_tts_play_task, NULL, &local_tts_play_thread_attr); osDelay(200/5); // 等待初始化完成 }